Overview

Exploration of all the data collected on the presence points + randomly generated background points

A note to anyone who might happen to stumble across this… I am a beginner in R and have had no exposure to similar languages. I don’t know what I’m doing. The code herein is unlikely to be elegant and there are probably more efficient ways of running the code.

Built with ‘r getRversion()’.

Package dependencies

You can load them using the following code which uses a function called ipak. Note this function checks to see if the packages are installed first. The “include=FALSE” supresses the package installation text appearing in the document…

read in all data

and subset into background and presences

presab <- read.csv("../output/bio/presab_10k.csv", header = TRUE)
presence <- subset(presab, occurrence == "1")
background <- subset(presab, occurrence == "0")

Update: Who sampled in which year and which month:

year

inst_by_yr <- with(presence, table(year, institutioncode))
write.csv(inst_by_yr, file = "../output/bio/institutioncode_by_yr.csv")
inst_by_yr
      institutioncode
year   ARC DFOCENARC DFOGulf DFOISDM DFOMTMS DFONL DFOQC MaineDMR NEFSC ROM
  1998   1         0      45       1      20   551     1        0     1   0
  1999   0         0      78       1      71   466     0        0     0   0
  2000   2         0      82       1      57   502     0        0     0   0
  2001   0         0      49       1      43   504     0        0     0   0
  2002   7         0      95       1      49   467     0        0     0   0
  2003   0         0      39       3      42   534     0        0     0   0
  2004   0         0      72       2      24   621   156        0     0   0
  2005   1        14      69       0      63   446   171        7     0   0
  2006   3        11      73       4      71   447   192        6     0   0
  2007   1        39      80       1      37   430   196        0     0   1
  2008   0        10      74       4      38   450   212        0     0   0
  2009   0        10      71       0      28   479    87        3     0   0
  2010   1         9      89       0      42   498    77        0     0   0
  2011   0        22      72       0      13   438    96        0     0   0
  2012   0         8      76       0      10     0   103        0     0   0
  2013   2        18      64       0      21     0    89        0     0   0
  2014   1        19      92       0       6     0     0        0     0   0
  2015   3        12       0       0       0     0     0        0     0   0

month

inst_by_mt <- with(presence, table(month, institutioncode))
write.csv(inst_by_mt, file = "../output/bio/institutioncode_by_mth.csv")
inst_by_mt
     institutioncode
month  ARC DFOCENARC DFOGulf DFOISDM DFOMTMS DFONL DFOQC MaineDMR NEFSC  ROM
   1     0         0       0       0       0   243     0        0     0    0
   2     0         0       0       0       6     4     0        0     0    0
   3     1         0       0       2     318     0     0        0     0    0
   4     0         0       0       3      11   682     0        0     1    0
   5     0         0       0       0       0  1015     2        8     0    0
   6     0         0       0       0       0  1562     4        3     0    0
   7     4        19       0       3     286    46    27        0     0    1
   8     1        71       6       1      14     0  1332        0     0    0
   9     8        20    1209       3       0     5    13        0     0    0
   10    0        61       5       3       0   520     2        2     0    0
   11    8         1       0       3       0  1722     0        3     0    0
   12    0         0       0       1       0  1034     0        0     0    0

and just a year-month table

year_by_mt <- with(presence, table(year, month))
write.csv(year_by_mt, file = "../output/bio/year_by_mth.csv")
year_by_mt
      month
year     1   2   3   4   5   6   7   8   9  10  11  12
  1998   0   0   0  59  81 131  20   0  45  78 195  11
  1999   0   0  46  42  61 152  25   0  78  10 145  57
  2000   0   0  41  42  55 117  19   0  82  35 178  75
  2001   0   5  24  69  77 100  15   0  49  24  86 148
  2002   0   0  32  74  78 106  17   0 102  37  73 100
  2003  54   0  23  70  91 127  19   0  40  35  54 105
  2004 120   0   0  51  81 125  26 143  82  28 105 114
  2005  17   4  28  22  66 106  39 181  70  46 149  43
  2006  52   1  50  21   5 124  26 201  74  65 107  81
  2007   0   0  20  52  52  93  70 200  80  37  96  85
  2008   0   0  30  36  76 125  30 202  71  27 130  61
  2009   0   0  10  66 144  55   8  83  73  33 159  47
  2010   0   0  17  39  68 113  25  85  94  65 152  58
  2011   0   0   0  54  90  95  11 108  67  63 103  50
  2012   0   0   0   0   0   0   8 113  76   0   0   0
  2013   0   0   0   0   0   0  27  94  64   7   2   0
  2014   0   0   0   0   0   0   1  11 103   3   0   0
  2015   0   0   0   0   0   0   0   4   8   0   3   0

environmental correlates

  1. Get the max, min, an mean values and add into a dataframe

Temperature

temp_depth_max <- max(presence$temp_depth, na.rm = TRUE)
temp_depth_min <- min(presence$temp_depth, na.rm = TRUE)
temp_depth_mean <- mean(presence$temp_depth, na.rm = TRUE)
temp_surface_max <- max(presence$temp_surface, na.rm = TRUE)
temp_surface_min <- min(presence$temp_surface, na.rm = TRUE)
temp_surface_mean <- mean(presence$temp_surface, na.rm = TRUE)

Salinity

sal_depth_max <- max(presence$salinity_depth, na.rm = TRUE)
sal_depth_min <- min(presence$salinity_depth, na.rm = TRUE)
sal_depth_mean <- mean(presence$salinity_depth, na.rm = TRUE)
sal_surface_max <- max(presence$salinity_surface, na.rm = TRUE)
sal_surface_min <- min(presence$salinity_surface, na.rm = TRUE)
sal_surface_mean <- mean(presence$salinity_surface, na.rm = TRUE)

Chl

chl_depth_max <- max(presence$chl_depth, na.rm = TRUE)
chl_depth_min <- min(presence$chl_depth, na.rm = TRUE)
chl_depth_mean <- mean(presence$chl_depth, na.rm = TRUE)
chl_surface_max <- max(presence$chl_surface, na.rm = TRUE)
chl_surface_min <- min(presence$chl_surface, na.rm = TRUE)
chl_surface_mean <- mean(presence$chl_surface, na.rm = TRUE)

O2

o2_depth_max <- max(presence$o2_depth, na.rm = TRUE)
o2_depth_min <- min(presence$o2_depth, na.rm = TRUE)
o2_depth_mean <- mean(presence$o2_depth, na.rm = TRUE)
o2_surface_max <- max(presence$o2_surface, na.rm = TRUE)
o2_surface_min <- min(presence$o2_surface, na.rm = TRUE)
o2_surface_mean <- mean(presence$o2_surface, na.rm = TRUE)

MLP

mlp_surface_max <- max(presence$mlp_surface, na.rm = TRUE)
mlp_surface_min <- min(presence$mlp_surface, na.rm = TRUE)
mlp_surface_mean <- mean(presence$mlp_surface, na.rm = TRUE)

SSH

ssh_surface_max <- max(presence$ssh_surface, na.rm = TRUE)
ssh_surface_min <- min(presence$ssh_surface, na.rm = TRUE)
ssh_surface_mean <- mean(presence$ssh_surface, na.rm = TRUE)

create matrix

td <- c(temp_depth_max, temp_depth_min, temp_depth_mean)
ts <- c(temp_surface_max, temp_surface_min, temp_surface_mean)
sd <- c(sal_depth_max, sal_depth_min, sal_depth_mean)
ss <- c(sal_surface_max, sal_surface_min, sal_surface_mean)
cd <- c(sal_depth_max, sal_depth_min, sal_depth_mean)
cs <- c(sal_surface_max, sal_surface_min, sal_surface_mean)
od <- c(o2_depth_max, o2_depth_min, o2_depth_mean)
os <- c(o2_surface_max, o2_surface_min, o2_surface_mean)
mlp <- c(mlp_surface_max, mlp_surface_min, mlp_surface_mean)
ssh <- c(ssh_surface_max, ssh_surface_min, ssh_surface_mean)
env_stats <- rbind(td, ts, sd, ss, cd, cs, od, os, mlp, ssh)
row.names(env_stats) <- c("Temp Depth", "Temp Surface", "Salinity Depth", "Salinity Surface", "Chl Depth", "Chl Surface", "Oxygen Depth", "Oxygen Surface", "MLP", "SSH") 
colnames(env_stats) <- c("Max", "Min", "Mean")
write.csv(env_stats, "../output/env/env_correlates_basic_stats.csv", row.names = TRUE)
env_stats
                         Max         Min        Mean
Temp Depth       289.0834045 271.2114868 274.9217164
Temp Surface     293.3608093 271.6101074 280.4476878
Salinity Depth    35.5045395  22.1449070  33.4295117
Salinity Surface  34.3667259  13.5929441  30.2518319
Chl Depth         35.5045395  22.1449070  33.4295117
Chl Surface       34.3667259  13.5929441  30.2518319
Oxygen Depth     377.2959595   0.9998450 279.6701444
Oxygen Surface   385.2262878 238.3178253 315.1620514
MLP              108.2339201  10.6823719  18.1911518
SSH               -0.2825949  -0.8503166  -0.5334292

Hmm some potentially suspicious values here in - Oxygen Depth min - mlp Max and maybe also - Salinity Depth min - Salinity Surface min - CHL depth min - CHL depth max

lets just see where these values appear and check the netcdf layers. Note I will check these values in cygwin using the cdo operator infov on the netcdfs (to ensure there was no issue with processing in R).

get the year and month these values appeared in

o2d_check_yr <- subset(presence$year, presence$o2_depth == o2_depth_min)
o2d_check_mth <- subset(presence$month, presence$o2_depth == o2_depth_min)

O2 depth min is in 2005_08

And value seems correct

mlp_check_yr <- subset(presence$year, presence$mlp_surface == mlp_surface_max)
mlp_check_mth <- subset(presence$month, presence$mlp_surface == mlp_surface_max)

mlp max in in 2007_12

And yes the value seems correct

sald_check_yr <- subset(presence$year, presence$salinity_depth == sal_depth_max)
sald_check_mth <- subset(presence$month, presence$salinity_depth == sal_depth_max)

year month 2001_05

also seems correct

sals_check_yr <- subset(presence$year, presence$salinity_surface == sal_surface_min)
sals_check_mth <- subset(presence$month, presence$salinity_surface == sal_surface_min)

year month 21998_06

ok again…

Leave the rest

simple plots of env. correlates

temperature

par(mfrow=c(1,2))
plot(presence$temp_depth, main = "Temp at Depth (Various)", ylab = "Kelvin")
plot(presence$temp_surface, main = "Temp at Surface", ylab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

Hmm not necessarily very helpful. But anyway, lets carry on

salinity

par(mfrow=c(1,2))
plot(presence$salinity_depth, main = "Salinity at Depth (Various)", ylab = "Practical Salinity Units")
plot(presence$salinity_surface, main = "Salinity at Surface", ylab = "Practical Salinity Units")
dev.copy(png,"../output/env/simple_plots/salinity_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

Chlorophyll

par(mfrow=c(1,2))
plot(presence$chl_depth, main = "Chl at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(presence$chl_surface, main = "Chl at Surface", ylab = "Chl (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/chl_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

O2

par(mfrow=c(1,2))
plot(presence$o2_depth, main = "Dissolved Oxygen at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(presence$o2_surface, main = "Dissolved Oxygen at Surface", ylab = "O2 (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/o2_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

mlp

plot(presence$mlp_surface, main = "Mixed Layer Thickness", ylab = "Depth (m)")
dev.copy(png,"../output/env/simple_plots/mlp_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

SSH

plot(presence$ssh_surface, main = "Sea Surface Height", ylab = "Height (m)")
dev.copy(png,"../output/env/simple_plots/ssh_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

XXX SAM - YOU WANT TO THINK ABOUT DOING THIS BY DEPTH RATHER THAN ALL DEPTHS)

unique_depths <- unique(presence$depthlayerno)
unique_depthdordered <- sort(unique_depths) #just puts the list in oder with no NA
length(unique_depthdordered)
[1] 39

ouch - 39 layers… a job for a boxplot probably

frequency plots of env. corr

temperature

hist(presence$temp_surface, main = "Temp at Surface", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(presence$temp_dept, main = "Temp at Depth", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

chl

hist(presence$chl_surface, main = "Chlorophyll at Surface", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(presence$chl_depth, main = "Chlorophyll at Observation Depth", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

salinity

hist(presence$salinity_surface, main = "Salinity at Surface", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(presence$salinity_depth, main = "Salinity at Observation Depth", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

oxygen

hist(presence$o2_surface, main = "Dissolved Oxygen at Surface", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(presence$o2_depth, main = "Dissolved Oxygen at Observation Depth", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

MLP

hist(presence$mlp, main = "Mixed Layer Thickness at Observation", xlab = "Mixed Layer Thickness (m)")
dev.copy(png, "../output/env/simple_plots/mlp_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ssh

hist(presence$ssh, main = "Sea Surface Height at Observation", xlab = "Sea Surface Height (m)")
dev.copy(png, "../output/env/simple_plots/ssh_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

simple boxplots of env. corr

Same as above but with boxplots (may provide some more useful info)

individual plots of each variable

par(mfrow=c(1,2))
boxplot(presence$chl_depth, main = "Chlorphyll at Depth (Various)", ylab = "mmol.m-3")
boxplot(presence$chl_surface, main = "Chlorphyll at Surface", ylab = "mmol.m-3")
dev.copy(png, "../output/env/simple_plots/chl_boxplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$temp_depth ~ presence$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$chl_depth ~ presence$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$salinity_depth ~ presence$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$o2_depth ~ presence$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation Depth per Month")
dev.copy(png, "../output/env/simple_plots/o2_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$mlp_surface ~ presence$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Observation per Month")
dev.copy(png, "../output/env/simple_plots/mlp_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$ssh_surface ~ presence$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Observation per Month")
dev.copy(png, "../output/env/simple_plots/ssh_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$temp_depth ~ presence$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$chl_depth ~ presence$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/chl_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$salinity_depth ~ presence$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$o2_depth ~ presence$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation Depth per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$mlp ~ presence$year, xlab = "Year", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Observation per Year")
dev.copy(png, "../output/env/simple_plots/mlp_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$ssh ~ presence$year, xlab = "Year", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Observation per Year")
dev.copy(png, "../output/env/simple_plots/ssh_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$temp_surface ~ presence$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$chl_surface ~ presence$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$salinity_surface ~ presence$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$o2_surface ~ presence$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/o2_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$mlp_surface ~ presence$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Observation per Month")
dev.copy(png, "../output/env/simple_plots/mlp_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$ssh_surface ~ presence$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Observation per Month")
dev.copy(png, "../output/env/simple_plots/ssh_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$temp_surface ~ presence$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$chl_surface ~ presence$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/chl_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$salinity_surface ~ presence$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/salinity_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(presence$o2_surface ~ presence$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Observation (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

background points

environmental correlates

  1. Get the max, min, an mean values and add into a dataframe

Temperature

temp_depth_max_back <- max(background$temp_depth, na.rm = TRUE)
temp_depth_min_back <- min(background$temp_depth, na.rm = TRUE)
temp_depth_mean_back <- mean(background$temp_depth, na.rm = TRUE)
temp_surface_max_back <- max(background$temp_surface, na.rm = TRUE)
temp_surface_min_back <- min(background$temp_surface, na.rm = TRUE)
temp_surface_mean_back <- mean(background$temp_surface, na.rm = TRUE)

Salinity

sal_depth_max_back <- max(background$salinity_depth, na.rm = TRUE)
sal_depth_min_back <- min(background$salinity_depth, na.rm = TRUE)
sal_depth_mean_back <- mean(background$salinity_depth, na.rm = TRUE)
sal_surface_max_back <- max(background$salinity_surface, na.rm = TRUE)
sal_surface_min_back <- min(background$salinity_surface, na.rm = TRUE)
sal_surface_mean_back <- mean(background$salinity_surface, na.rm = TRUE)

Chl

chl_depth_max_back <- max(background$chl_depth, na.rm = TRUE)
chl_depth_min_back <- min(background$chl_depth, na.rm = TRUE)
chl_depth_mean_back <- mean(background$chl_depth, na.rm = TRUE)
chl_surface_max_back <- max(background$chl_surface, na.rm = TRUE)
chl_surface_min_back <- min(background$chl_surface, na.rm = TRUE)
chl_surface_mean_back <- mean(background$chl_surface, na.rm = TRUE)

O2

o2_depth_max_back <- max(background$o2_depth, na.rm = TRUE)
o2_depth_min_back <- min(background$o2_depth, na.rm = TRUE)
o2_depth_mean_back <- mean(background$o2_depth, na.rm = TRUE)
o2_surface_max_back <- max(background$o2_surface, na.rm = TRUE)
o2_surface_min_back <- min(background$o2_surface, na.rm = TRUE)
o2_surface_mean_back <- mean(background$o2_surface, na.rm = TRUE)

MLP

mlp_surface_max_back <- max(background$mlp_surface, na.rm = TRUE)
mlp_surface_min_back <- min(background$mlp_surface, na.rm = TRUE)
mlp_surface_mean_back <- mean(background$mlp_surface, na.rm = TRUE)

SSH

ssh_surface_max_back <- max(background$ssh_surface, na.rm = TRUE)
ssh_surface_min_back <- min(background$ssh_surface, na.rm = TRUE)
ssh_surface_mean_back <- mean(background$ssh_surface, na.rm = TRUE)

create matrix

tdb <- c(temp_depth_max_back, temp_depth_min_back, temp_depth_mean_back)
tsb <- c(temp_surface_max_back, temp_surface_min_back, temp_surface_mean_back)
sdb <- c(sal_depth_max_back, sal_depth_min_back, sal_depth_mean_back)
ssb <- c(sal_surface_max_back, sal_surface_min_back, sal_surface_mean_back)
cdb <- c(sal_depth_max_back, sal_depth_min_back, sal_depth_mean_back)
csb <- c(sal_surface_max_back, sal_surface_min_back, sal_surface_mean_back)
odb <- c(o2_depth_max_back, o2_depth_min_back, o2_depth_mean_back)
osb <- c(o2_surface_max_back, o2_surface_min_back, o2_surface_mean_back)
mlpb <- c(mlp_surface_max_back, mlp_surface_min_back, mlp_surface_mean_back)
sshb <- c(ssh_surface_max_back, ssh_surface_min_back, ssh_surface_mean_back)
env_stats_back <- rbind(tdb, tsb, sdb, ssb, cdb, csb, odb, osb, mlpb, sshb)
row.names(env_stats_back) <- c("Temp Depth", "Temp Surface", "Salinity Depth", "Salinity Surface", "Chl Depth", "Chl Surface", "Oxygen Depth", "Oxygen Surface", "MLP", "SSH") 
colnames(env_stats_back) <- c("Max", "Min", "Mean")
write.csv(env_stats_back, "../output/env/env_correlates_background_basic_stats.csv", row.names = TRUE)
env_stats_back
                          Max         Min        Mean
Temp Depth        296.6814000 270.4851000 276.9213399
Temp Surface      298.0739000 271.0959000 278.3042248
Salinity Depth     36.1154400  13.4615900  33.2171443
Salinity Surface   35.7264900  12.5724900  32.2697238
Chl Depth          36.1154400  13.4615900  33.2171443
Chl Surface        35.7264900  12.5724900  32.2697238
Oxygen Depth      460.2821000   0.9636452 303.3679603
Oxygen Surface    405.9796000 207.9546000 320.6152836
MLP              2237.7090000   8.5859600  39.0529201
SSH                -0.2319994  -1.2355570  -0.6758784

temperature

par(mfrow=c(1,2))
plot(background$temp_depth, main = "Background Points Temp at Depth (Various)", ylab = "Kelvin")
plot(background$temp_surface, main = "Background Points Temp at Surface", ylab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

salinity

par(mfrow=c(1,2))
plot(background$salinity_depth, main = "Background Points Salinity at Depth (Various)", ylab = "Practical Salinity Units")
plot(background$salinity_surface, main = "Background Points Salinity at Surface", ylab = "Practical Salinity Units")
dev.copy(png,"../output/env/simple_plots/salinity_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

Chlorophyll

par(mfrow=c(1,2))
plot(background$chl_depth, main = "Background Points Chl at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(background$chl_surface, main = "Background Points Chl at Surface", ylab = "Chl (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/chl_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

O2

par(mfrow=c(1,2))
plot(background$o2_depth, main = "Background Points Dissolved Oxygen at Depth (Various)", ylab = "Chl (mmol.m-3)")
plot(background$o2_surface, main = "Background Points Dissolved Oxygen at Surface", ylab = "O2 (mmol.m-3)")
dev.copy(png,"../output/env/simple_plots/o2_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

mlp

plot(background$mlp_surface, main = "Background Points Mixed Layer Thickness", ylab = "Depth (m)")
dev.copy(png,"../output/env/simple_plots/mlp_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

SSH

plot(background$ssh_surface, main = "Background Points Sea Surface Height", ylab = "Height (m)")
dev.copy(png,"../output/env/simple_plots/ssh_background_simpleplot.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

frequency plots of env. corr

temperature

hist(background$temp_surface, main = "Background Temp at Surface", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(background$temp_dept, main = "Background Temp at Depth", xlab = "Kelvin")
dev.copy(png, "../output/env/simple_plots/temperature_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

chl

hist(background$chl_surface, main = "Background Chlorophyll at Surface", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(background$chl_depth, main = "Background Chlorophyll at Observation Depth", xlab = "Chlorophyll Concentrations (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/chl_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

salinity

hist(background$salinity_surface, main = "Background Salinity at Surface", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(background$salinity_depth, main = "Background Salinity at Observation Depth", xlab = "Salinity Practical Salinity Unit (PSU)")
dev.copy(png, "../output/env/simple_plots/sal_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

oxygen

hist(background$o2_surface, main = "Background Dissolved Oxygen at Surface", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

hist(background$o2_depth, main = "Background Dissolved Oxygen at Observation Depth", xlab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)")
dev.copy(png, "../output/env/simple_plots/o2_background_depth_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

MLP

hist(background$mlp, main = "Background Mixed Layer Thickness at Observation", xlab = "Mixed Layer Thickness (m)")
dev.copy(png, "../output/env/simple_plots/mlp_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ssh

hist(background$ssh, main = "Background Sea Surface Height at Observation", xlab = "Sea Surface Height (m)")
dev.copy(png, "../output/env/simple_plots/ssh_background_surface_histogram.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

simple boxplots of env. corr

Same as above but with boxplots (may provide some more useful info)

temperature

boxplot(background$temp_depth ~ background$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$chl_depth ~ background$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$salinity_depth ~ background$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$o2_depth ~ background$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background Depth per Month")
dev.copy(png, "../output/env/simple_plots/o2_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$mlp_surface ~ background$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Background per Month")
dev.copy(png, "../output/env/simple_plots/mlp_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$ssh_surface ~ background$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Background per Month")
dev.copy(png, "../output/env/simple_plots/ssh_background_boxplot_dept_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$temp_depth ~ background$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$chl_depth ~ background$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/chl_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$salinity_depth ~ background$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$o2_depth ~ background$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background Depth per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$mlp ~ background$year, xlab = "Year", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Background per Year")
dev.copy(png, "../output/env/simple_plots/mlp_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$ssh ~ background$year, xlab = "Year", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Background per Year")
dev.copy(png, "../output/env/simple_plots/ssh_background_boxplot_dept_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$temp_surface ~ background$month, xlab = "month", ylab = "Temperature (Kelvin)", main = "Temperature at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$chl_surface ~ background$month, xlab = "month", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/chlorophyll_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$salinity_surface ~ background$month, xlab = "month", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$o2_surface ~ background$month, xlab = "month", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background (Surface) per Month")
dev.copy(png, "../output/env/simple_plots/o2_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$mlp_surface ~ background$month, xlab = "month", ylab = "Mixed Layer Thickness (m)", main = "Mixed Layer Thickness at Background per Month")
dev.copy(png, "../output/env/simple_plots/mlp_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$ssh_surface ~ background$month, xlab = "month", ylab = "Sea Surface Height (m)", main = "Sea Surface Height at Background per Month")
dev.copy(png, "../output/env/simple_plots/ssh_background_boxplot_surface_month.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$temp_surface ~ background$year, xlab = "Year", ylab = "Temperature (Kelvin)", main = "Temperature at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/temperature_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$chl_surface ~ background$year, xlab = "Year", ylab = "Chlorophyll Concentrations (mmol.m-3)", main = "Chlorophyll at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/chl_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$salinity_surface ~ background$year, xlab = "Year", ylab = "Salinity Practical Salinity Unit (PSU)", main = "Salinity at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/salinity_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

boxplot(background$o2_surface ~ background$year, xlab = "Year", ylab = "Mole Concentration of Dissolved Oxygen in Sea Water (mmol.m-3)", main = "Dissolved Oxygen at Background (Surface) per Year")
dev.copy(png, "../output/env/simple_plots/oxygen_background_boxplot_surface_year.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

correlations between background points

check to see if there are any correlations in the env. variables for the background points

first subset the env.correlate columns (you don’t need everything)

background_env <- subset(background, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth))
background_env_cor <- cor(background_env, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(background_env_cor, "../output/env/background_env_corr.csv", row.names = TRUE)
background_corrplot <- corrplot(background_env_cor , method = "color", type = "upper", order = "alphabet", tl.cex = 0.8) 
dev.copy(png,"../output/env/simple_plots/background_envcorr.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

to get some density plots all in one graphic, you need to change chunk output to in console, then go to the plot tab, make it fill the screen, then run then make bigger then save :( (probably a better way - this seems to be an issue with RStudio)

par(mfrow=c(4,4))
for(i in 1:16){
  plot(density(background_env[,i], na.rm=T), main = names(background_env)[i])
}

PUT THE CHUNK OUTPUT BACK TO INLINE

add nafo region and gear type into the mix CANT!!

first subset the env.correlate columns + bottom_depth (you don’t need everything)

background_envbotdepth <- subset(background, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
background_envbotdepth_cor <- cor(background_envbotdepth, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(background_envbotdepth_cor, "../output/env/background_envbotdepth_cor.csv", row.names = TRUE)
background_corrplot <- corrplot(background_envbotdepth_cor , method = "color", type = "upper", order = "alphabet", tl.cex = 0.8) 
dev.copy(png,"../output/env/simple_plots/background_envbotdepth_cor.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

correlations between presence points

check to see if there are any correlations in the env. variables

first subset the env.correlate columns (you don’t need everything) then use cor to get the correlation values, and then corrplot for a visual

pres_env <- subset(presence, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
pres_env_cor <- cor(pres_env, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(pres_env_cor, "../output/env/pres_env_corr.csv", row.names = TRUE)
pres_corrplot <- corrplot(pres_env_cor , method = "color", type = "upper", order = "alphabet", tl.cex = 0.8) 
dev.copy(png,"../output/env/simple_plots/pres_envcorr.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

to get some density plots all in one graphic, you need to change chunk output to in console, then go to the plot tab, make it fill the screen, then run then make bigger then save :( (probably a better way - this seems to be an issue with RStudio)

graphics.off()
tiff("../output/env/simple_plots/background_envcorr_density.tiff") # to automatically save the plot to a png AND show it inline
par(mfrow=c(4,4), mar=c(1,1,1,1))
for(i in 1:16){
  plot(density(pres_env[,i], na.rm=T), main = names(pres_env)[i])
}
dev.off() # stops automatic saving of the plot to a png
null device 
          1 

PUT THE CHUNK OUTPUT BACK TO INLINE

density plot with background and presence env. data

Inspired by Merrow 2013 - top paragraph of page 1063 (are the species observations uniformly distributed over the background, or are they skewed)

ggplot(pres_env, aes(x = temp_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/temp_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = temp_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/temp_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = chl_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/chl_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = chl_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/chl_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = salinity_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/salinity_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = salinity_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/salinity_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = o2_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/o2_surface_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = o2_depth)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/o2_depth_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = mlp_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/mlp_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(pres_env, aes(x = ssh_surface)) + geom_density(na.rm = TRUE, colour = "red") + geom_density(data=background_env, na.rm = TRUE, colour = "blue")
dev.copy(png,"../output/env/simple_plots/ssh_backvspres.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

NAFO Regions

compare the environmental correlates between different NAFO regions

first see which nafo zones were sampled in each year

nafo_by_yr
      nafo_zone
year    0A  0B  1C  2G  2H  2J  3K  3L  3M  3N  3O 3Pn 3Ps  4R  4S  4T 4Vn 4Vs  4W  4X  5Y 5Ze HudsonStrait
  1998   0   0   0   0  12  55 106 211   0  42  68   2  55   0   0  46   8   7   4   3   1   0            0
  1999   0   0   0   0   0  34  93 196   0  40  47   2  54   0   0  76   9  34  27   2   2   0            0
  2000   0   0   0   0   0  51 111 194   2  50  46   4  46   0   0  82  12  26  19   1   0   0            0
  2001   0   0   0   0   3  34 109 200   0  48  53   2  55   0   0  49   6  28  10   0   0   0            0
  2002   0   0   0   0   0  33  65 207   0  46  56   4  57   0   0 101   8  27  14   1   0   0            0
  2003   0   0   0   0   0  46  60 214   0  60  72   3  79   0   0  40   8  20  15   1   0   0            0
  2004   0   0   0   0   8  56 194 181   0  52  61   6  63  36  63 128  10  11   5   1   0   0            0
  2005   0   7   0   7   0  46  86 187   0  37  49   1  40  41  86 113  19  20  21   4   7   0            0
  2006   3   4   0   3  13  43 166 164   0  22  24   0  18  23 105 130  11  34  27   9   7   1            0
  2007   0  10   0   3   0  32  79 156   0  51  54   1  59  25 100 150   9  19  11   0   0   0           26
  2008   3   7   0   0   6  48  75 156   0  43  50   0  73  52 106 129   5  18  13   3   0   1            0
  2009   0   0   0   1   0  45  92 164   0  49  62   8  59  13  43 101   6   1  22   0   3   0            9
  2010   0   9   1   0   6  34 106 187   0  56  60   3  47  12  39 115  12  16  14   0   0   0            0
  2011   0   9   0   1   5  35  75 147   0  64  45  10  57  23  43 101   6   6   2   0   0   0           12
  2012   0   7   0   1   0   0   0   0   0   0   0   0   0  23  50 106   5   1   3   1   0   0            0
  2013   0   3   0   6   1   0   0   2   0   0   0   0   0  21  44  88  15   2   4   0   0   0            8
  2014   1  13   0   1   0   0   0   1   0   0   0   0   0   0   0  92   6   0   0   0   0   0            4
  2015   0   8   0   1   0   0   0   2   0   0   0   0   1   0   0   0   0   0   0   0   0   0            3

and by month

nafo_by_mth <- with(presence, table(nafo_zone, month))
write.csv(nafo_by_mth, file = "../output/bio/nafozone_by_mth.csv")
nafo_by_mth
              month
nafo_zone         1    2    3    4    5    6    7    8    9   10   11   12
  0A              0    0    0    0    0    0    0    3    0    3    1    0
  0B              0    0    0    0    0    0    0   53   20    4    0    0
  1C              0    0    0    0    0    0    0    1    0    0    0    0
  2G              0    0    0    0    0    0   16    8    0    0    0    0
  2H              0    0    0    0    0    0    2    0    0   49    0    3
  2J              6    0    0    0    0    0    0    0    0  119  363  104
  3K            235    4    0    0    0    0    0    2    0    0  575  601
  3L              2    0    0    0   98 1305   47    1    0   62  730  324
  3M              0    0    0    0    0    0    0    0    0    2    0    0
  3N              0    0    0    0  283  229    0    0    0  106   40    2
  3O              0    0    0   28  480   28    1    0    5  182   22    1
  3Pn             0    0    0   39    7    0    0    0    0    0    0    0
  3Ps             0    0    0  615  147    0    0    0    0    0    1    0
  4R              0    0    0    0    0    0   15  253    1    0    0    0
  4S              0    0    0    0    2    1    4  670    2    0    0    0
  4T              0    0    0    0    0    3    8  413 1216    7    0    0
  4Vn             0    0    0    1    0    0  132    8   14    0    0    0
  4Vs             0    0  169    2    0    0   96    3    0    0    0    0
  4W              0    5  148   11    0    0   41    4    0    1    1    0
  4X              0    0    3    0    0    0   20    0    0    2    1    0
  5Y              0    0    0    1    8    3    3    0    0    2    3    0
  5Ze             0    1    1    0    0    0    0    0    0    0    0    0
  HudsonStrait    0    0    0    0    0    0    1    7    0   54    0    0

Interesting that there is a point in 1C - this is outside Canadian waters remove from the dataset

presab <- presab[!(presab$nafo_zone == "1C" & presab$occurrence == "1"), ]
write.csv(presab, "../output/bio/presab_10k.csv", row.names = FALSE)
presence <- presence[!(presence$nafo_zone == "1C"), ]

and by month again

nafo_by_mth <- with(presence, table(nafo_zone, month))
write.csv(nafo_by_mth, file = "../output/bio/nafozone_by_mth.csv")
nafo_by_mth
              month
nafo_zone         1    2    3    4    5    6    7    8    9   10   11   12
  0A              0    0    0    0    0    0    0    3    0    3    1    0
  0B              0    0    0    0    0    0    0   53   20    4    0    0
  1C              0    0    0    0    0    0    0    0    0    0    0    0
  2G              0    0    0    0    0    0   16    8    0    0    0    0
  2H              0    0    0    0    0    0    2    0    0   49    0    3
  2J              6    0    0    0    0    0    0    0    0  119  363  104
  3K            235    4    0    0    0    0    0    2    0    0  575  601
  3L              2    0    0    0   98 1305   47    1    0   62  730  324
  3M              0    0    0    0    0    0    0    0    0    2    0    0
  3N              0    0    0    0  283  229    0    0    0  106   40    2
  3O              0    0    0   28  480   28    1    0    5  182   22    1
  3Pn             0    0    0   39    7    0    0    0    0    0    0    0
  3Ps             0    0    0  615  147    0    0    0    0    0    1    0
  4R              0    0    0    0    0    0   15  253    1    0    0    0
  4S              0    0    0    0    2    1    4  670    2    0    0    0
  4T              0    0    0    0    0    3    8  413 1216    7    0    0
  4Vn             0    0    0    1    0    0  132    8   14    0    0    0
  4Vs             0    0  169    2    0    0   96    3    0    0    0    0
  4W              0    5  148   11    0    0   41    4    0    1    1    0
  4X              0    0    3    0    0    0   20    0    0    2    1    0
  5Y              0    0    0    1    8    3    3    0    0    2    3    0
  5Ze             0    1    1    0    0    0    0    0    0    0    0    0
  HudsonStrait    0    0    0    0    0    0    1    7    0   54    0    0

density plot with background and presence env. data by NAFO region

What I want to see if if there is a marked difference between the env. correlates of the presence points between NAFO regions. This is also to try deal with sampling bias (b/c the whole region is not uniformly sampled in each month, but rather nafo regions have a strong month bias)

first create NAFO-region datasets

nafo0a <- subset(presence, nafo_zone == "0A")
nafo0b <- subset(presence, nafo_zone == "0B")
nafo2g <- subset(presence, nafo_zone == "2G")
nafo2h <- subset(presence, nafo_zone == "2H")
nafo2j <- subset(presence, nafo_zone == "2J")
nafo3k <- subset(presence, nafo_zone == "3K")
nafo3l <- subset(presence, nafo_zone == "3L")
nafo3m <- subset(presence, nafo_zone == "3M")
nafo3n <- subset(presence, nafo_zone == "3N")
nafo3o <- subset(presence, nafo_zone == "3O")
nafo3ps <- subset(presence, nafo_zone == "3Ps")
nafo4r <- subset(presence, nafo_zone == "4R")
nafo4s <- subset(presence, nafo_zone == "4S")
nafo4t <- subset(presence, nafo_zone == "4T")
nafo4vn <- subset(presence, nafo_zone == "4Vn")
nafo4vs <- subset(presence, nafo_zone == "4Vs")
nafo4w <- subset(presence, nafo_zone == "4W")
nafo4x <- subset(presence, nafo_zone == "4X")
nafo5y <- subset(presence, nafo_zone == "5Y")
nafo5ze <- subset(presence, nafo_zone == "5ZE")
nafohudson <- subset(presence, nafo_zone == "HudsonStrait")

plot by each variable, less 3m (2 samples) and 5ze (2 samples)

ggplot(nafo0a, aes(x = temp_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/temp_surface_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(nafo0a, aes(x = temp_depth, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/temp_depth_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(nafo0a, aes(x = chl_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/chl_surface_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(nafo0a, aes(x = chl_depth, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/chl_depth_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(nafo0a, aes(x = salinity_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/salinity_surface_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(nafo0a, aes(x = salinity_depth, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/salinity_depth_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(nafo0a, aes(x = o2_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/o2_surface_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(nafo0a, aes(x = o2_depth, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/o2_depth_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(nafo0a, aes(x = mlp_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/mlp_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(nafo0a, aes(x = ssh_surface, colour = nafo_zone)) + geom_density(na.rm = TRUE) + geom_density(data=nafo0b, na.rm = TRUE) + geom_density(data=nafo2g, na.rm = TRUE) + geom_density(data=nafo2h, na.rm = TRUE) + geom_density(data=nafo2j, na.rm = TRUE) + geom_density(data=nafo3k, na.rm = TRUE) + geom_density(data=nafo3l, na.rm = TRUE) + geom_density(data=nafo3n, na.rm = TRUE) + geom_density(data=nafo3o, na.rm = TRUE) + geom_density(data=nafo3ps, na.rm = TRUE) + geom_density(data=nafo4r, na.rm = TRUE) + geom_density(data=nafo4s, na.rm = TRUE) + geom_density(data=nafo4t, na.rm = TRUE) + geom_density(data=nafo4vn, na.rm = TRUE) + geom_density(data=nafo4vs, na.rm = TRUE) + geom_density(data=nafo4w, na.rm = TRUE) + geom_density(data=nafo4x, na.rm = TRUE) + geom_density(data=nafo5y, na.rm = TRUE) + geom_density(data=nafohudson, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_nafo_plots/ssh_nafo.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

Let’s plot the variables by nafo region/year then by month

pr98 <- subset(presence, year == "1998")
boxplot(pr98$temp_depth ~ pr98$nafo_zone, xlab = "NAFO Region", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per NAFO Zone")
pr98 <- subset(presence, year == "1998")
pr11 <- subset(presence, year == "2011")
par(mfrow=c(2,1))
boxplot(pr98$temp_depth ~ pr98$nafo_zone, xlab = "NAFO Region", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per NAFO Zone")
boxplot(pr11$temp_depth ~ pr11$nafo_zone, xlab = "NAFO Region", ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth per NAFO Zone")

ok scrap the nafo region analysis - it is too mixed up with month (so seeing if region or month is a factor that needs to be factored in to the model is not appropriate)

remap who sampled

Now lets check the number of records and spatial-temporal distribution of the observations by institution code to make sure none are dodgy

first a table of how many observations each instituioncode has

obs_by_ins <- count(presence, "institutioncode")
obs_by_ins
write.csv(obs_by_ins, file = "../output/bio/samplinginstitutions/no_observations_institutioncode.csv")

ok so NEFSC and ROM only have one point each

Lets take a look at the spatial breakdown of these institutions.First all points…

map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(38, 70), asp = 1, main = "All Occurrences", col = "cornsilk") #the x and y lim are the long-lat bounds of the map
points(presence$decimalLongitude, presence$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/all_occurrences.png") #this prints a png of the plot
png 
  3 
dev.off() #this turns off the print command
png 
  2 

Note there is one point up by iceland that you should get rid of (Icelandic population thought to be seperate from Labrador, but it is unclear if this is true or not).

Map the institutioncode == ARC only data…

ROM_obs <- presence[presence$institutioncode == "ROM", ]
map2 <- getMap(resolution = "low") #creates an object called map at low resoultion
plot(map2, xlim = c(-70, -43), ylim =c(39, 70), asp = 1, main = "Royal Ontario Museum Occurrences",  col = "cornsilk") #the x and y lim are the long-lat bounds of the map

points(ROM_obs$decimalLongitude, ROM_obs$decimalLatitude, col = "red") #this adds points to the mapet", xlab = "Longitude", ylab = "Latitude")
dev.copy(png, "../output/bio/samplinginstitutions/ROM_occurrences_all.png") #this prints a png of the plot
png 
  3 

check for gear type

what are the unique gear types you have in your presence data, and how many?

gear_count <- count(presence, "gear")
write.csv(gear_count, file = "../output/bio/gear_count.csv")
gear_count

so the vast majority are trawls of some type.

map the gear usage in Arcgis (gear_type_map)

create a table of gear use by month

gearby_mth <- with(presence, table(gear, month))
write.csv(gearby_mth, file = "../output/bio/gear_by_mth.csv")
gearby_mth
                            month
gear                            1    2    3    4    5    6    7    8    9   10   11   12
  bottom_trawl                  0    6  318   12    8    3  286   14    0    2    3    0
  bottom_trawl_alfredo_03       0    0    0    0    0    0    0    0    0    3    0    0
  bottom_trawl_campelen_14      0    0    0    0    0    0   18   33    0    0    0    0
  bottom_trawl_campelen_1800  243    4    0  682 1015 1562   56  841   10  520 1722 1034
  bottom_trawl_campelen_21      0    0    0    0    0    0    1   35   20    0    0    0
  bottom_trawl_cosmos_2600      0    0    0    0    0    0    0    3    0   58    1    0
  bottom_trawl_western_IIA      0    0    0    0    0    0    0    6 1209    5    0    0
  unknown                       0    0    1    0    2    4   22  492   16    2    8    0
  vertical_plankton_tow         0    0    2    3    0    0    3    1    3    3    3    1

What I want to see if if there is a marked difference between the env. correlates of the presence points between gear type used. This is also to try deal with detection bias between gear type (b/c the whole region is not uniformly sampled by the same gear type)

first create gear datasets

presence$gear <- as.character(presence$gear)
bottom_trawl <- subset(presence, gear == "bottom_trawl")
bottom_trawl_alfredo_03 <- subset(presence, gear == "bottom_trawl_alfredo_03")
bottom_trawl_campelen_14 <- subset(presence, gear == "bottom_trawl_campelen_14")
bottom_trawl_campelen_1800 <- subset(presence, gear == "bottom_trawl_campelen_1800")
bottom_trawl_campelen_21 <- subset(presence, gear == "bottom_trawl_campelen_21")
bottom_trawl_cosmos_2600 <- subset(presence, gear == "bottom_trawl_cosmos_2600")
bottom_trawl_western_IIA <- subset(presence, gear == "bottom_trawl_western_IIA")
unknown <- subset(presence, gear == "unknown")
vertical_plankton_tow <- subset(presence, gear == "vertical_plankton_tow")

plot by each variable, less 3m (2 samples) 1c (one sample) and 5ze (zero samples?!)

ggplot(bottom_trawl, aes(x = temp_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/temp_surface_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(bottom_trawl, aes(x = temp_depth, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/temp_depth_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(bottom_trawl, aes(x = chl_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/chl_surface_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(bottom_trawl, aes(x = chl_depth, colour = gear))  + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/chl_depth_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(bottom_trawl, aes(x = salinity_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/salinity_surface_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(bottom_trawl, aes(x = salinity_depth, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/salinity_depth_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(bottom_trawl, aes(x = o2_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/o2_surface_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(bottom_trawl, aes(x = o2_depth, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/o2_depth_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(bottom_trawl, aes(x = mlp_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/mlp_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

ggplot(bottom_trawl, aes(x = ssh_surface, colour = gear)) + geom_density(na.rm = TRUE) + geom_density(data=bottom_trawl_alfredo_03, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_14, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_1800, na.rm = TRUE) + geom_density(data=bottom_trawl_campelen_21, na.rm = TRUE) + geom_density(data=bottom_trawl_cosmos_2600, na.rm = TRUE) + geom_density(data=bottom_trawl_western_IIA, na.rm = TRUE) + geom_density(data=unknown, na.rm = TRUE) + geom_density(data=vertical_plankton_tow, na.rm = TRUE)
dev.copy(png,"../output/env/env_by_gear_plots/ssh_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

par(mar=c(7,5,1,1))
boxplot(presence$temp_depth ~ presence$gear, ylab = "Temperature (Kelvin)", main = "Temperature at Observation Depth by gear type", las = 2)
dev.copy(png, "../output/env/simple_plots/temperature_boxplot_dept_gear.png") # to automatically save the plot to a png AND show it inline
png 
  3 
dev.off() # stops automatic saving of the plot to a png
png 
  2 

what about a kruskal wallace test?

kruskal.test(presence$temp_depth ~ presence$gear)

Ok so there is a statistically sig difference somewhere in the temp at depth reported by the gear type (Kruskal-Wallis chi-squared = 248.27, df = 7, p-value < 2.2e-16)

To see where the difference(s) are run a Dunn test Zar (2010) states that the Dunn test (in the FSA package) is appropriate for groups with unequal numbers of observations.(Zar, J.H. 2010. Biostatistical Analysis, 5th ed. Pearson Prentice Hall: Upper Saddle River, NJ.) http://rcompanion.org/rcompanion/d_06.html

SAM WHEN DUNN IS INSTALLED, GO TO RCOMPANIONS.ORG AND LOOK FOR DUNN - CHECK CHROME HISTORY (PROBABLY UNDER KRUSKAL WALLIS) ALSO MAP THE DISTRIBUTION OF THESE GEAR TYPES

pairwise.wilcox.test(presence$temp_depth, presence$gear, p.adj='bonferroni', exact=F)

dunn test

gear_temp_depthdunn <- dunnTest(presence$temp_depth, presence$gear, list = TRUE)
gear_temp_depthdunn



write.csv(table, "../output/env/gear_temp_depthdunn.csv", row.names = TRUE)

vif

for this you need the joined dataset.

vif_allpresab <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allpresab, "../output/bio/vif/vif_allpresab.csv", row.names = TRUE)
vif_allpresab
                      GVIF Df GVIF^(1/(2*Df))
temp_surface     29.568344  1        5.437678
temp_depth        2.179621  1        1.476354
salinity_surface  8.203658  1        2.864203
salinity_depth    5.680020  1        2.383279
o2_surface       28.595188  1        5.347447
o2_depth          5.294821  1        2.301048
chl_surface       3.524117  1        1.877263
chl_depth         2.558851  1        1.599641
bottom_depth      2.704882  1        1.644653
mlp_surface       1.972801  1        1.404564
ssh_surface       4.470089  1        2.114259
gear             11.472422  8        1.164739
nao_sample        1.151909  1        1.073270
nao_prev          1.130309  1        1.063160
nao_winter        1.093324  1        1.045621
amo_sample        4.954083  1        2.225777
amo_prev          5.084722  1        2.254933
amo_winter        1.129430  1        1.062747

interpret - see https://stats.stackexchange.com/questions/70679/which-variance-inflation-factor-should-i-be-using-textgvif-or-textgvif/96584#96584 To make GVIFs comparable across dimensions, we suggested using GVIF^(1/(2Df)), where Df is the number of coefficients in the subset (ref fox and motette 1992 in zotero) or the 2 continuous variables, GVIFˆ(1/(2Df)) (which is basically the square root of the VIF/GVIF value as DF=1) is the proportional change of the standard error and confidence interval of their coefficients due to the level of collinearity. The GVIFˆ(1/(2Df)) value of the categorical variable is a similar measure for the reduction in precision of the coefficients’ estimation due to collinearity. apparently i just need to square GVIF^(1/(2Df)) and then use the normal VIF “rule of thumb”…

vif_allpresab_sq <- read.csv("../output/bio/vif/vif_allpresab.csv", header = TRUE)
vif_allpresab_sq$GVIF2Dfsq <- vif_allpresab_sq$GVIF..1..2.Df..^2
write.csv(vif_allpresab_sq, "../output/bio/vif/vif_allpresab.csv", row.names = TRUE)
vif_allpresab_sq

As per SLR suggestion, rerun without gear

vif_allbutgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutgear, "../output/bio/vif/vif_allbutgear.csv", row.names = TRUE)
vif_allbutgear
    temp_surface       temp_depth salinity_surface   salinity_depth       o2_surface         o2_depth      chl_surface        chl_depth     bottom_depth      mlp_surface 
       11.465759         3.295722         4.826882         5.206847        12.958031         4.175056         2.306772         2.101983         2.857971         1.228628 
     ssh_surface       nao_sample         nao_prev       nao_winter       amo_sample         amo_prev       amo_winter 
        4.478627         1.094630         1.096453         1.102418         4.780916         4.851814         1.059102 

xx As per SLR suggestion, rerun without gear and most highly correlated variables

vif_allbutgearhighlycorr <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbutgearhighlycorr, "../output/bio/vif/vif_allbutgearhighlycorr.csv", row.names = TRUE)
vif_allbutgearhighlycorr
    temp_surface       temp_depth salinity_surface   salinity_depth         o2_depth      chl_surface      mlp_surface       nao_sample         nao_prev       nao_winter 
        2.920465         3.203729         4.186400         4.860349         3.065348         1.325612         1.112185         1.078420         1.079194         1.070659 
      amo_sample       amo_winter 
        1.253479         1.057472 

As per SLR suggestion, rerun with gear but without most highly correlated variables

vif_allbuthighlycorr <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter + gear, data = presab))
write.csv(vif_allbuthighlycorr, "../output/bio/vif/vif_allbuthighlycorr.csv", row.names = TRUE)
vif_allbuthighlycorr
                     GVIF Df GVIF^(1/(2*Df))
temp_surface     4.687780  1        2.165128
temp_depth       1.649841  1        1.284461
salinity_surface 6.480747  1        2.545731
salinity_depth   3.204241  1        1.790039
o2_depth         3.872181  1        1.967786
chl_surface      2.167748  1        1.472327
mlp_surface      1.781169  1        1.334605
nao_sample       1.126875  1        1.061544
nao_prev         1.102211  1        1.049862
nao_winter       1.055682  1        1.027464
amo_sample       1.332280  1        1.154244
amo_winter       1.104007  1        1.050718
gear             9.362047  8        1.150034
vif_allbuthighlycorr_sq <- read.csv("../output/bio/vif/vif_allbuthighlycorr.csv", header = TRUE)
vif_allbuthighlycorr_sq$GVIF2Dfsq <- vif_allbuthighlycorr_sq$GVIF..1..2.Df..^2
write.csv(vif_allbuthighlycorr_sq, "../output/bio/vif/vif_allbuthighlycorr.csv", row.names = TRUE)
vif_allbuthighlycorr_sq

ok remove one variable at a time - leave gear in

remove bottom_depth

vif_allbutbot_prev <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutbot_prev, "../output/bio/vif/vif_allbutbot_prev.csv", row.names = TRUE)
vif_allbutbot_prev <- read.csv("../output/bio/vif/vif_allbutbot_prev.csv", header = TRUE)
vif_allbutbot_prev$GVIF2Dfsq <- vif_allbutbot_prev$GVIF..1..2.Df..^2
write.csv(vif_allbutbot_prev, "../output/bio/vif/vif_allbutbot_prev.csv", row.names = TRUE)
vif_allbutbot_prev

and leave gear out

remove bottom_depth + gear

vif_allbutbot_prevgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutbot_prevgear, "../output/bio/vif/vif_allbutbot_prevgear.csv", row.names = TRUE)
vif_allbutbot_prevgear
    temp_surface       temp_depth salinity_surface   salinity_depth       o2_surface         o2_depth      chl_surface        chl_depth      mlp_surface      ssh_surface 
       11.354053         3.237083         4.825633         5.181528        12.945442         4.148216         2.291018         2.098356         1.228423         3.021062 
      nao_sample         nao_prev       nao_winter       amo_sample         amo_prev       amo_winter 
        1.093545         1.096446         1.102206         4.776866         4.851800         1.058909 

remove amo_prev

vif_allbutamo_prev <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbutamo_prev, "../output/bio/vif/vif_allbutamo_prev.csv", row.names = TRUE)
vif_allbutamo_prev <- read.csv("../output/bio/vif/vif_allbutamo_prev.csv", header = TRUE)
vif_allbutamo_prev$GVIF2Dfsq <- vif_allbutamo_prev$GVIF..1..2.Df..^2
write.csv(vif_allbutamo_prev, "../output/bio/vif/vif_allbutamo_prev.csv", row.names = TRUE)
vif_allbutamo_prev

and leave gear out

remove amo_prev + gear

vif_allbutamo_prevgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbutamo_prevgear, "../output/bio/vif/vif_allbutamo_prevgear.csv", row.names = TRUE)
vif_allbutamo_prevgear
    temp_surface       temp_depth salinity_surface   salinity_depth       o2_surface         o2_depth      chl_surface        chl_depth     bottom_depth      mlp_surface 
       11.347391         3.295716         4.826881         5.206384        12.765958         4.174880         2.304471         2.100476         2.857962         1.224003 
     ssh_surface       nao_sample         nao_prev       nao_winter       amo_sample       amo_winter 
        4.466039         1.080058         1.079727         1.073580         1.265428         1.058916 

remove chl_depth

vif_allbutchl_depth <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutchl_depth, "../output/bio/vif/vif_allbutchl_depth.csv", row.names = TRUE)
vif_allbutchl_depth <- read.csv("../output/bio/vif/vif_allbutchl_depth.csv", header = TRUE)
vif_allbutchl_depth$GVIF2Dfsq <- vif_allbutchl_depth$GVIF..1..2.Df..^2
write.csv(vif_allbutchl_depth, "../output/bio/vif/vif_allbutchl_depth.csv", row.names = TRUE)
vif_allbutchl_depth

remove chl_depth and gear

vif_allbutchl_depthgear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutchl_depthgear, "../output/bio/vif/vif_allbutchl_depthgear.csv", row.names = TRUE)
vif_allbutchl_depthgear
    temp_surface       temp_depth salinity_surface   salinity_depth       o2_surface         o2_depth      chl_surface     bottom_depth      mlp_surface      ssh_surface 
       11.465368         3.286337         4.763276         5.202900        12.629715         3.253857         1.763718         2.853040         1.227709         4.463921 
      nao_sample         nao_prev       nao_winter       amo_sample         amo_prev       amo_winter 
        1.094594         1.096371         1.102390         4.780796         4.848337         1.059043 

remove ssh_surface

vif_allbutssh_surface <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutssh_surface, "../output/bio/vif/vif_allbutssh_surface.csv", row.names = TRUE)
vif_allbutssh_surface <- read.csv("../output/bio/vif/vif_allbutssh_surface.csv", header = TRUE)
vif_allbutssh_surface$GVIF2Dfsq <- vif_allbutssh_surface$GVIF..1..2.Df..^2
write.csv(vif_allbutssh_surface, "../output/bio/vif/vif_allbutssh_surface.csv", row.names = TRUE)
vif_allbutssh_surface

remove ssh_surface & gear

vif_allbutssh_surfacegear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutssh_surfacegear, "../output/bio/vif/vif_allbutssh_surfacegear.csv", row.names = TRUE)
vif_allbutssh_surfacegear
    temp_surface       temp_depth salinity_surface   salinity_depth       o2_surface         o2_depth      chl_surface        chl_depth     bottom_depth      mlp_surface 
       10.046950         3.293527         4.585939         5.072030        11.450006         4.054837         2.113070         2.095081         1.927847         1.182305 
      nao_sample         nao_prev       nao_winter       amo_sample         amo_prev       amo_winter 
        1.093310         1.096432         1.100775         4.746652         4.838178         1.058444 

remove o2_surface

vif_allbuto2_surface <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuto2_surface, "../output/bio/vif/vif_allbuto2_surface.csv", row.names = TRUE)
vif_allbuto2_surface <- read.csv("../output/bio/vif/vif_allbuto2_surface.csv", header = TRUE)
vif_allbuto2_surface$GVIF2Dfsq <- vif_allbuto2_surface$GVIF..1..2.Df..^2
write.csv(vif_allbuto2_surface, "../output/bio/vif/vif_allbuto2_surface.csv", row.names = TRUE)
vif_allbuto2_surface

remove o2_surface & gear

vif_allbuto2_surfacegear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuto2_surfacegear, "../output/bio/vif/vif_allbuto2_surfacegear.csv", row.names = TRUE)
vif_allbuto2_surfacegear
    temp_surface       temp_depth salinity_surface   salinity_depth         o2_depth      chl_surface        chl_depth     bottom_depth      mlp_surface      ssh_surface 
        3.230352         3.293953         4.763841         5.155372         3.880777         1.788680         2.048725         2.855194         1.224247         3.957415 
      nao_sample         nao_prev       nao_winter       amo_sample         amo_prev       amo_winter 
        1.094604         1.096448         1.102310         4.720633         4.779897         1.058061 

as per SLR chat jan 23:

remove salinity_surface only

vif_allbutsalinitysurface <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutsalinitysurface, "../output/bio/vif/vif_allbutsalinitysurface.csv", row.names = TRUE)
vif_allbutsalinitysurface <- read.csv("../output/bio/vif/vif_allbutsalinitysurface.csv", header = TRUE)
vif_allbutsalinitysurface$GVIF2Dfsq <- vif_allbutsalinitysurface$GVIF..1..2.Df..^2
write.csv(vif_allbutsalinitysurface, "../output/bio/vif/vif_allbutsalinitysurface.csv", row.names = TRUE)
vif_allbutsalinitysurface

and without gear

vif_allbutsalinitysurfacegear <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbutsalinitysurfacegear, "../output/bio/vif/vif_allbutsalinitysurfacegear.csv", row.names = TRUE)
vif_allbutsalinitysurfacegear
  temp_surface     temp_depth salinity_depth     o2_surface       o2_depth    chl_surface      chl_depth   bottom_depth    mlp_surface    ssh_surface     nao_sample       nao_prev 
     11.063264       2.549610       2.633799      12.788795       2.814414       2.301361       2.074284       2.857231       1.227348       4.255068       1.094397       1.096250 
    nao_winter     amo_sample       amo_prev     amo_winter 
      1.102205       4.766710       4.851814       1.059071 

remove temp_surface only

vif_allbuttempsurface <- vif(lm(occurrence ~ temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuttempsurface, "../output/bio/vif/vif_allbuttempsurface.csv", row.names = TRUE)
vif_allbuttempsurface <- read.csv("../output/bio/vif/vif_allbuttempsurface.csv", header = TRUE)
vif_allbuttempsurface$GVIF2Dfsq <- vif_allbuttempsurface$GVIF..1..2.Df..^2
write.csv(vif_allbuttempsurface, "../output/bio/vif/vif_allbuttempsurface.csv", row.names = TRUE)
vif_allbuttempsurface
vif_allbuttempsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuttempsurfacegear, "../output/bio/vif/vif_allbuttempsurfacegear.csv", row.names = TRUE)
vif_allbuttempsurfacegear
      temp_depth salinity_surface   salinity_depth       o2_surface         o2_depth      chl_surface        chl_depth     bottom_depth      mlp_surface      ssh_surface 
        3.072096         4.657438         5.058933         3.650783         4.062894         2.195182         2.101911         2.830127         1.215545         3.924427 
      nao_sample         nao_prev       nao_winter       amo_sample         amo_prev       amo_winter 
        1.092118         1.096043         1.101830         4.646480         4.801726         1.057256 

now remove temp_surface plus highly correlated

#with gear
vif_allbuthighcorrtempsurface <- vif(lm(occurrence ~ temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + mlp_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsurface, "../output/bio/vif/vif_allbuthighcorrtempsurface.csv", row.names = TRUE)
vif_allbuthighcorrtempsurface <- read.csv("../output/bio/vif/vif_allbuthighcorrtempsurface.csv", header = TRUE)
vif_allbuthighcorrtempsurface$GVIF2Dfsq <- vif_allbuthighcorrtempsurface$GVIF..1..2.Df..^2
write.csv(vif_allbuthighcorrtempsurface, "../output/bio/vif/vif_allbuthighcorrtempsurface.csv", row.names = TRUE)
vif_allbuthighcorrtempsurface
#without gear
vif_allbuthighcorrtempsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_surface + salinity_depth + o2_depth + chl_surface + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsurfacegear, "../output/bio/vif/vif_allbuthighcorrtempsurfacegear.csv", row.names = TRUE)
vif_allbuthighcorrtempsurfacegear
      temp_depth salinity_surface   salinity_depth         o2_depth      chl_surface      mlp_surface       nao_sample         nao_prev       nao_winter       amo_sample 
        2.063406         3.936504         4.736628         3.064882         1.172481         1.098150         1.071556         1.077449         1.069530         1.169899 
      amo_winter 
        1.056621 

now remove temp_surface plus salinity_surface

#with gear
vif_allbuttempsalsurface <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuttempsalsurface, "../output/bio/vif/vif_allbuttempsalsurface.csv", row.names = TRUE)
vif_allbuttempsalsurface <- read.csv("../output/bio/vif/vif_allbuttempsalsurface.csv", header = TRUE)
vif_allbuttempsalsurface$GVIF2Dfsq <- vif_allbuttempsalsurface$GVIF..1..2.Df..^2
write.csv(vif_allbuttempsalsurface, "../output/bio/vif/vif_allbuttempsalsurface.csv", row.names = TRUE)
vif_allbuttempsalsurface
#without gear
vif_allbuttempsalsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = presab))
write.csv(vif_allbuttempsalsurfacegear, "../output/bio/vif/vif_allbuttempsalsurfacegear.csv", row.names = TRUE)
vif_allbuttempsalsurfacegear
    temp_depth salinity_depth     o2_surface       o2_depth    chl_surface      chl_depth   bottom_depth    mlp_surface    ssh_surface     nao_sample       nao_prev     nao_winter 
      2.449336       2.626476       3.624181       2.800383       2.175973       2.072655       2.826585       1.215331       3.535876       1.091487       1.095706       1.101725 
    amo_sample       amo_prev     amo_winter 
      4.609894       4.799836       1.057063 

now remove temp_surface plus salinity_surface + highly correlated

#with gear
vif_allbuthighcorrtempsalsurface <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + mlp_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsalsurface, "../output/bio/vif/vif_allbuthighcorrtempsalsurface.csv", row.names = TRUE)
vif_allbuthighcorrtempsalsurface <- read.csv("../output/bio/vif/vif_allbuthighcorrtempsalsurface.csv", header = TRUE)
vif_allbuthighcorrtempsalsurface$GVIF2Dfsq <- vif_allbuthighcorrtempsalsurface$GVIF..1..2.Df..^2
write.csv(vif_allbuthighcorrtempsalsurface, "../output/bio/vif/vif_allbuthighcorrtempsalsurface.csv", row.names = TRUE)
vif_allbuthighcorrtempsalsurface
#without gear
vif_allbuthighcorrtempsalsurfacegear <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + mlp_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = presab))
write.csv(vif_allbuthighcorrtempsalsurfacegear, "../output/bio/vif/vif_allbuthighcorrtempsalsurfacegear.csv", row.names = TRUE)
vif_allbuthighcorrtempsalsurfacegear
    temp_depth salinity_depth       o2_depth    chl_surface    mlp_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      1.536582       1.314145       1.670188       1.167592       1.085566       1.070786       1.076759       1.069452       1.138991       1.056420 

Just out of curiosity, a vif will all but but atmos drivers

vif_allbutnaoamo <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + gear, data = presab))
write.csv(vif_allbutnaoamo, "../output/bio/vif/vif_allbutnaoamo.csv", row.names = TRUE)
vif_allbutnaoamo <- read.csv("../output/bio/vif/vif_allbutnaoamo.csv", header = TRUE)
vif_allbutnaoamo$GVIF2Dfsq <- vif_allbutnaoamo$GVIF..1..2.Df..^2
write.csv(vif_allbutnaoamo, "../output/bio/vif/vif_allbutnaoamo.csv", row.names = TRUE)
vif_allbutnaoamo

not much diff..

monthly spearmans correlations and VIF

curious - does correlations/vif alter between months?

First split the dataset into monthly

presab$gear <- as.character(presab$gear)
janpresab <- subset(presab, month == "1")
febpresab <- subset(presab, month == "2")
marpresab <- subset(presab, month == "3")
aprpresab <- subset(presab, month == "4")
maypresab <- subset(presab, month == "5")
junpresab <- subset(presab, month == "6")
julpresab <- subset(presab, month == "7")
augpresab <- subset(presab, month == "8")
seppresab <- subset(presab, month == "9")
octpresab <- subset(presab, month == "10")
novpresab <- subset(presab, month == "11")
decpresab <- subset(presab, month == "12")

now get the background points for each month (for spearmans)

janback <- subset(janpresab, occurrence == "0")
febback <- subset(febpresab, occurrence == "0")
marback <- subset(marpresab, occurrence == "0")
aprback <- subset(aprpresab, occurrence == "0")
mayback <- subset(maypresab, occurrence == "0")
junback <- subset(junpresab, occurrence == "0")
julback <- subset(julpresab, occurrence == "0")
augback <- subset(augpresab, occurrence == "0")
sepback <- subset(seppresab, occurrence == "0")
octback <- subset(octpresab, occurrence == "0")
novback <- subset(novpresab, occurrence == "0")
decback <- subset(decpresab, occurrence == "0")

run the correlations on each month’s background points

janback <- subset(janback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
janback_cor <- cor(janback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(janback_cor, "../output/env/janback_cor.csv", row.names = TRUE)
febback <- subset(febback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
febback_cor <- cor(febback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(febback_cor, "../output/env/febback_cor.csv", row.names = TRUE)
marback <- subset(marback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
marback_cor <- cor(marback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(marback_cor, "../output/env/marback_cor.csv", row.names = TRUE)
aprback <- subset(aprback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
aprback_cor <- cor(aprback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(aprback_cor, "../output/env/aprback_cor.csv", row.names = TRUE)
mayback <- subset(mayback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
mayback_cor <- cor(mayback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(mayback_cor, "../output/env/mayback_cor.csv", row.names = TRUE)
junback <- subset(junback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
junback_cor <- cor(junback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(junback_cor, "../output/env/junback_cor.csv", row.names = TRUE)
julback <- subset(julback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
julback_cor <- cor(julback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(julback_cor, "../output/env/julback_cor.csv", row.names = TRUE)
augback <- subset(augback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
augback_cor <- cor(augback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(augback_cor, "../output/env/augback_cor.csv", row.names = TRUE)
sepback <- subset(sepback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
sepback_cor <- cor(sepback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(sepback_cor, "../output/env/sepback_cor.csv", row.names = TRUE)
octback <- subset(octback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
octback_cor <- cor(octback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(octback_cor, "../output/env/octback_cor.csv", row.names = TRUE)
novback <- subset(novback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
novback_cor <- cor(novback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(novback_cor, "../output/env/novback_cor.csv", row.names = TRUE)
decback <- subset(decback, select = c(amo_sample, amo_winter, amo_prev, nao_sample, nao_winter, nao_prev, chl_surface, chl_depth, mlp_surface, ssh_surface, temp_surface, temp_depth, o2_surface, o2_depth, salinity_surface, salinity_depth, bottom_depth))
decback_cor <- cor(decback, use="complete.obs", method = "spearman") #need to create a correlation using cor to plot. complete.obs means na.rm in this package. #using spearmans as suitable for non-linear relationships
write.csv(decback_cor, "../output/env/decback_cor.csv", row.names = TRUE)

Run a VIF for each month (with and without gear)

vif_nogear_jan <- vif(lm(occurrence ~ temp_surface + temp_depth + salinity_surface + salinity_depth + o2_surface + o2_depth + chl_surface + chl_depth + bottom_depth + mlp_surface + ssh_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_prev + amo_winter, data = janpresab))
Error in vif.default(lm(occurrence ~ temp_surface + temp_depth + salinity_surface +  : 
  there are aliased coefficients in the model

spearmans indicates chl_depth, mlp_surface, ssh_surface, temp_surface, o2_surface, salinity_surface, and bottom_depth, amo_prev (and for Jun and Oct chl_surface; and for jan amo_winter, ampo_prev, amo_sample, and NAO_prev, and feb amo_winter, ampo_prev, amo_sample, nao winter, and NAO_prev) all correlated every month. remove from each model and rerun Run a VIF for each month (with and without gear)

#with gear - for jan there is none because there is only one category of gear
#without gear
vif_nogear_cor_jan <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface+ nao_sample + nao_winter, data = janpresab))
write.csv(vif_nogear_cor_jan, "../output/bio/vif/monthly_vifs/vif_nogear_cor_jan.csv", row.names = TRUE)
vif_nogear_cor_jan
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample     nao_winter 
      2.168252       2.551701       2.459972       1.742686       1.324866       1.316335 
#without gear
vif_nogear_cor_feb <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface  + nao_sample, data = febpresab))
write.csv(vif_nogear_cor_feb, "../output/bio/vif/monthly_vifs/vif_nogear_cor_feb.csv", row.names = TRUE)
vif_nogear_cor_feb
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample 
      2.636138       2.224945       2.376624       1.565463       1.007649 
#with gear
vif_gear_cor_mar <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = marpresab))
write.csv(vif_gear_cor_mar, "../output/bio/vif/monthly_vifs/vif_gear_cor_mar.csv", row.names = TRUE)
vif_gear_cor_mar <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_mar.csv", header = TRUE)
vif_gear_cor_mar$GVIF2Dfsq <- vif_gear_cor_mar$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_mar, "../output/bio/vif/monthly_vifs/vif_gear_cor_mar.csv", row.names = TRUE)
vif_gear_cor_mar
#without gear
vif_nogear_cor_mar <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = marpresab))
write.csv(vif_nogear_cor_mar, "../output/bio/vif/monthly_vifs/vif_nogear_cor_mar.csv", row.names = TRUE)
vif_nogear_cor_mar
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      2.255506       1.977242       2.266471       1.296972       1.440578       1.429102       1.516391       1.436118       1.087738 
#with gear
vif_gear_cor_apr <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = aprpresab))
write.csv(vif_gear_cor_apr, "../output/bio/vif/monthly_vifs/vif_gear_cor_apr.csv", row.names = TRUE)
vif_gear_cor_apr <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_apr.csv", header = TRUE)
vif_gear_cor_apr$GVIF2Dfsq <- vif_gear_cor_apr$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_apr, "../output/bio/vif/monthly_vifs/vif_gear_cor_apr.csv", row.names = TRUE)
vif_gear_cor_apr
#without gear
vif_nogear_cor_apr <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = aprpresab))
write.csv(vif_nogear_cor_apr, "../output/bio/vif/monthly_vifs/vif_nogear_cor_apr.csv", row.names = TRUE)
vif_nogear_cor_apr
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      1.859268       1.555059       2.085310       1.094040       3.303144       1.692901       4.099749       2.271605       1.239617 
#with gear
vif_gear_cor_may <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = maypresab))
write.csv(vif_gear_cor_may, "../output/bio/vif/monthly_vifs/vif_gear_cor_may.csv", row.names = TRUE)
#without gear
vif_nogear_cor_may <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = maypresab))
write.csv(vif_nogear_cor_may, "../output/bio/vif/monthly_vifs/vif_nogear_cor_may.csv", row.names = TRUE)
vif_nogear_cor_may
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      1.736955       1.380981       1.792550       1.379057       1.673749       4.310307       3.694028       2.508993       1.155045 
#with gear
vif_gear_cor_jun <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = junpresab))
write.csv(vif_gear_cor_jun, "../output/bio/vif/monthly_vifs/vif_gear_cor_jun.csv", row.names = TRUE)
vif_gear_cor_jun
    temp_depth salinity_depth       o2_depth    chl_surface           gear     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      2.528495       3.801194       1.894963       2.489998       1.086078       1.212537       1.414383       1.107102       1.771964       1.113434 
#without gear
vif_nogear_cor_jun <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = junpresab))
write.csv(vif_nogear_cor_jun, "../output/bio/vif/monthly_vifs/vif_nogear_cor_jun.csv", row.names = TRUE)
vif_nogear_cor_jun
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      1.542758       1.301562       1.638559       1.457845       1.181152       1.388201       1.058340       1.531045       1.055746 
#with gear
vif_gear_cor_jul <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = julpresab))
essentially perfect fit: summary may be unreliable
write.csv(vif_gear_cor_jul, "../output/bio/vif/monthly_vifs/vif_gear_cor_jul.csv", row.names = TRUE)
vif_gear_cor_jul <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_jul.csv", header = TRUE)
vif_gear_cor_jul$GVIF2Dfsq <- vif_gear_cor_jul$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_jul, "../output/bio/vif/monthly_vifs/vif_gear_cor_jul.csv", row.names = TRUE)
vif_gear_cor_jul
#without gear
vif_nogear_cor_jul <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = julpresab))
write.csv(vif_nogear_cor_jul, "../output/bio/vif/monthly_vifs/vif_nogear_cor_jul.csv", row.names = TRUE)
vif_nogear_cor_jul
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      1.543069       1.325558       1.521027       1.206177       2.928616       2.496408       1.641297       1.298534       1.604576 
#with gear
vif_gear_cor_aug <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = augpresab))
write.csv(vif_gear_cor_aug, "../output/bio/vif/monthly_vifs/vif_gear_cor_aug.csv", row.names = TRUE)
vif_gear_cor_aug <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_aug.csv", header = TRUE)
vif_gear_cor_aug$GVIF2Dfsq <- vif_gear_cor_aug$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_aug, "../output/bio/vif/monthly_vifs/vif_gear_cor_aug.csv", row.names = TRUE)
vif_gear_cor_aug
#without gear
vif_nogear_cor_aug <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = augpresab))
write.csv(vif_nogear_cor_aug, "../output/bio/vif/monthly_vifs/vif_nogear_cor_aug.csv", row.names = TRUE)
vif_nogear_cor_aug
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      1.536373       1.318218       1.315348       1.138970       1.382785       1.708867       1.341438       1.657683       1.158012 
#with gear
vif_gear_cor_sep <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = seppresab))
write.csv(vif_gear_cor_sep, "../output/bio/vif/monthly_vifs/vif_gear_cor_sep.csv", row.names = TRUE)
vif_gear_cor_sep <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_sep.csv", header = TRUE)
vif_gear_cor_sep$GVIF2Dfsq <- vif_gear_cor_sep$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_sep, "../output/bio/vif/monthly_vifs/vif_gear_cor_sep.csv", row.names = TRUE)
vif_gear_cor_sep
#without gear
vif_nogear_cor_sep <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = seppresab))
write.csv(vif_nogear_cor_sep, "../output/bio/vif/monthly_vifs/vif_nogear_cor_sep.csv", row.names = TRUE)
vif_nogear_cor_sep
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      1.428756       1.194681       1.224031       1.210142       2.019480       1.745438       1.639778       1.203383       1.733592 
#with gear
vif_gear_cor_oct <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = octpresab))
write.csv(vif_gear_cor_oct, "../output/bio/vif/monthly_vifs/vif_gear_cor_oct.csv", row.names = TRUE)
vif_gear_cor_oct
                   GVIF Df GVIF^(1/(2*Df))
temp_depth     3.320049  1        1.822100
salinity_depth 3.853326  1        1.962989
o2_depth       4.823800  1        2.196315
chl_surface    3.027180  1        1.739879
gear           5.115930  5        1.177314
nao_sample     1.464780  1        1.210281
nao_prev       4.402273  1        2.098160
nao_winter     1.444378  1        1.201823
amo_sample     2.191129  1        1.480246
amo_winter     2.923263  1        1.709755
vif_gear_cor_oct <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_oct.csv", header = TRUE)
vif_gear_cor_oct$GVIF2Dfsq <- vif_gear_cor_oct$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_oct, "../output/bio/vif/monthly_vifs/vif_gear_cor_oct.csv", row.names = TRUE)
vif_gear_cor_oct
#without gear
vif_nogear_cor_oct <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = octpresab))
write.csv(vif_nogear_cor_oct, "../output/bio/vif/monthly_vifs/vif_nogear_cor_oct.csv", row.names = TRUE)
vif_nogear_cor_oct
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      1.674621       1.320634       1.429731       1.421107       1.374528       3.414508       1.220549       2.089117       2.206526 
#with gear
vif_gear_cor_nov <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = novpresab))
essentially perfect fit: summary may be unreliable
write.csv(vif_gear_cor_nov, "../output/bio/vif/monthly_vifs/vif_gear_cor_nov.csv", row.names = TRUE)
vif_gear_cor_nov <- read.csv("../output/bio/vif/monthly_vifs/vif_gear_cor_nov.csv", header = TRUE)
vif_gear_cor_nov$GVIF2Dfsq <- vif_gear_cor_nov$GVIF..1..2.Df..^2
write.csv(vif_gear_cor_nov, "../output/bio/vif/monthly_vifs/vif_gear_cor_nov.csv", row.names = TRUE)
vif_gear_cor_nov
#without gear
vif_nogear_cor_nov <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = novpresab))
write.csv(vif_nogear_cor_nov, "../output/bio/vif/monthly_vifs/vif_nogear_cor_nov.csv", row.names = TRUE)
vif_nogear_cor_nov
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      1.598138       1.491446       1.730198       1.311339       1.363302       1.207681       1.072291       1.626908       1.685992 
#with gear
vif_gear_cor_dec <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + gear + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = decpresab))
write.csv(vif_gear_cor_dec, "../output/bio/vif/monthly_vifs/vif_gear_cor_dec.csv", row.names = TRUE)
vif_gear_cor_dec
    temp_depth salinity_depth       o2_depth    chl_surface           gear     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      5.929754      16.230010       8.351577       1.565082       1.320044       1.869436       1.405118       1.596288       1.375816       1.327107 
#without gear
vif_nogear_cor_dec <- vif(lm(occurrence ~ temp_depth + salinity_depth + o2_depth + chl_surface + nao_sample + nao_prev + nao_winter + amo_sample + amo_winter, data = decpresab))
write.csv(vif_nogear_cor_dec, "../output/bio/vif/monthly_vifs/vif_nogear_cor_dec.csv", row.names = TRUE)
vif_nogear_cor_dec
    temp_depth salinity_depth       o2_depth    chl_surface     nao_sample       nao_prev     nao_winter     amo_sample     amo_winter 
      1.515588       1.873634       2.176190       1.436543       1.840590       1.374077       1.532668       1.245253       1.305000 

in the presences, which rows are missing either temp_depth, salinity_depth, or o2_depth?

fmatch("o2_depth", names(presencemerging)) #32
[1] 32
fmatch("salinity_depth", names(presencemerging)) #34
[1] 34
fmatch("temp_depth", names(presencemerging)) #37
[1] 37
presence_wdepth_noo2 <- presence[is.na(presence$o2_depth), ]
nrow(presence_wdepth_noo2) #just to check it has mapped
[1] 3098
presence_wdepth_nosalinity <- presence[is.na(presence$salinity_depth), ]
nrow(presence_wdepth_nosalinity) #just to check it has mapped
[1] 3729
presence_wdepth_notemp <- presence[is.na(presence$temp_depth), ]
nrow(presence_wdepth_notemp) #just to check it has mapped
[1] 3729

ok remove all rows where temp_depth is missing (3729 rows)

presab_missingvals <- presab[!is.na(presab$temp_depth), ]
nrow(presab_missingvals) #130299 - correct
[1] 126570

check for missing vals

presence_wdepth_noo2 <- presab_missingvals[is.na(presab_missingvals$o2_depth), ]
nrow(presence_wdepth_noo2) #just to check it has mapped
[1] 210
presence_wdepth_nosalinity <- presab_missingvals[is.na(presab_missingvals$salinity_depth), ]
nrow(presence_wdepth_nosalinity) #just to check it has mapped
[1] 0
presence_wdepth_notemp <- presab_missingvals[is.na(presab_missingvals$temp_depth), ]
nrow(presence_wdepth_notemp) #just to check it has mapped
[1] 0

ok now remove row where o2_depth is missing

presab_missingvals <- presab_missingvals[!is.na(presab_missingvals$o2_depth), ]
nrow(presab_missingvals) #130299 - correct
[1] 126360

ok as summaries observations per month

and before it was…

just check the obs that you removed (saved as presence_na.csv) to see if the reported depth is deeper than the gebco derrived bottom depth

ok potentially i might be able to claw back 150 points…im not sure its worth it

maxent?

library("raster")
Loading required package: sp
LS0tDQp0aXRsZTogIkRhdGEgRXhwbG9yYXRpb24iDQphdXRob3I6ICJTYW1hbnRoYSBBbmRyZXdzIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazogDQogICAgZmlnX2hlaWdodDogNw0KICAgIGZpZ193aWR0aDogMTANCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCiMgT3ZlcnZpZXcNCkV4cGxvcmF0aW9uIG9mIGFsbCB0aGUgZGF0YSBjb2xsZWN0ZWQgb24gdGhlIHByZXNlbmNlIHBvaW50cyArIHJhbmRvbWx5IGdlbmVyYXRlZCBiYWNrZ3JvdW5kIHBvaW50cw0KDQpBIG5vdGUgdG8gYW55b25lIHdobyBtaWdodCBoYXBwZW4gdG8gc3R1bWJsZSBhY3Jvc3MgdGhpcy4uLiBJIGFtIGEgYmVnaW5uZXIgaW4gUiBhbmQgaGF2ZSBoYWQgbm8gZXhwb3N1cmUgdG8gc2ltaWxhciBsYW5ndWFnZXMuIEkgZG9uJ3Qga25vdyB3aGF0IEknbSBkb2luZy4gVGhlIGNvZGUgaGVyZWluIGlzIHVubGlrZWx5IHRvIGJlIGVsZWdhbnQgYW5kIHRoZXJlIGFyZSBwcm9iYWJseSBtb3JlIGVmZmljaWVudCB3YXlzIG9mIHJ1bm5pbmcgdGhlIGNvZGUuDQoNCkJ1aWx0IHdpdGggJ3IgZ2V0UnZlcnNpb24oKScuDQoNCiMgUGFja2FnZSBkZXBlbmRlbmNpZXMNCllvdSBjYW4gbG9hZCB0aGVtIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29kZSB3aGljaCB1c2VzIGEgZnVuY3Rpb24gY2FsbGVkIFtpcGFrXShodHRwczovL2dpc3QuZ2l0aHViLmNvbS9zdGV2ZW53b3J0aGluZ3Rvbi8zMTc4MTYzKS4gDQpOb3RlIHRoaXMgZnVuY3Rpb24gY2hlY2tzIHRvIHNlZSBpZiB0aGUgcGFja2FnZXMgYXJlIGluc3RhbGxlZCBmaXJzdC4NClRoZSAiaW5jbHVkZT1GQUxTRSIgc3VwcmVzc2VzIHRoZSBwYWNrYWdlIGluc3RhbGxhdGlvbiB0ZXh0IGFwcGVhcmluZyBpbiB0aGUgZG9jdW1lbnQuLi4NCmBgYHtyIHByZS1pbnN0YWxsIHBhY2thZ2VzLCBpbmNsdWRlPUZBTFNFfQ0KcGFja2FnZXMgPC0gYygicGx5ciIsICJncmFwaGljcyIsICJnZ3Bsb3QyIiwgImNvcnJwbG90IiwgIkZTQSIsICJjYXIiLCAicndvcmxkbWFwIiwgImZhc3RtYXRjaCIpIA0Kc291cmNlKCIuLi9zcmMvaXBhay5SIikNCmlwYWsocGFja2FnZXMpDQpgYGANCg0KIyByZWFkIGluIGFsbCBkYXRhDQoNCmFuZCBzdWJzZXQgaW50byBiYWNrZ3JvdW5kIGFuZCBwcmVzZW5jZXMNCmBgYHtyfQ0KcHJlc2FiIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ByZXNhYl8xMGsuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnByZXNlbmNlIDwtIHN1YnNldChwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjEiKQ0KYmFja2dyb3VuZCA8LSBzdWJzZXQocHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCmBgYA0KDQojIyBVcGRhdGU6IFdobyBzYW1wbGVkIGluIHdoaWNoIHllYXIgYW5kIHdoaWNoIG1vbnRoOg0KDQp5ZWFyDQpgYGB7ciBvYnNlcnZhdGlvbnMgYnkgaW5zdGl0dXRlLXllYXJ9DQppbnN0X2J5X3lyIDwtIHdpdGgocHJlc2VuY2UsIHRhYmxlKHllYXIsIGluc3RpdHV0aW9uY29kZSkpDQp3cml0ZS5jc3YoaW5zdF9ieV95ciwgZmlsZSA9ICIuLi9vdXRwdXQvYmlvL2luc3RpdHV0aW9uY29kZV9ieV95ci5jc3YiKQ0KaW5zdF9ieV95cg0KYGBgDQoNCm1vbnRoDQpgYGB7ciBvYnNlcnZhdGlvbnMgYnkgaW5zdGl0dXRlLW1vbnRofQ0KaW5zdF9ieV9tdCA8LSB3aXRoKHByZXNlbmNlLCB0YWJsZShtb250aCwgaW5zdGl0dXRpb25jb2RlKSkNCndyaXRlLmNzdihpbnN0X2J5X210LCBmaWxlID0gIi4uL291dHB1dC9iaW8vaW5zdGl0dXRpb25jb2RlX2J5X210aC5jc3YiKQ0KaW5zdF9ieV9tdA0KYGBgDQoNCmFuZCBqdXN0IGEgeWVhci1tb250aCB0YWJsZQ0KYGBge3Igb2JzZXJ2YXRpb25zIGJ5IHllYXItbW9udGh9DQp5ZWFyX2J5X210IDwtIHdpdGgocHJlc2VuY2UsIHRhYmxlKHllYXIsIG1vbnRoKSkNCndyaXRlLmNzdih5ZWFyX2J5X210LCBmaWxlID0gIi4uL291dHB1dC9iaW8veWVhcl9ieV9tdGguY3N2IikNCnllYXJfYnlfbXQNCmBgYA0KDQoNCg0KIyMgZW52aXJvbm1lbnRhbCBjb3JyZWxhdGVzDQoNCjEpIEdldCB0aGUgbWF4LCBtaW4sIGFuIG1lYW4gdmFsdWVzIGFuZCBhZGQgaW50byBhIGRhdGFmcmFtZQ0KDQpUZW1wZXJhdHVyZQ0KYGBge3J9DQp0ZW1wX2RlcHRoX21heCA8LSBtYXgocHJlc2VuY2UkdGVtcF9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KdGVtcF9kZXB0aF9taW4gPC0gbWluKHByZXNlbmNlJHRlbXBfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnRlbXBfZGVwdGhfbWVhbiA8LSBtZWFuKHByZXNlbmNlJHRlbXBfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnRlbXBfc3VyZmFjZV9tYXggPC0gbWF4KHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KdGVtcF9zdXJmYWNlX21pbiA8LSBtaW4ocHJlc2VuY2UkdGVtcF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNClNhbGluaXR5DQpgYGB7cn0NCnNhbF9kZXB0aF9tYXggPC0gbWF4KHByZXNlbmNlJHNhbGluaXR5X2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpzYWxfZGVwdGhfbWluIDwtIG1pbihwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbmEucm0gPSBUUlVFKQ0Kc2FsX2RlcHRoX21lYW4gPC0gbWVhbihwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbmEucm0gPSBUUlVFKQ0Kc2FsX3N1cmZhY2VfbWF4IDwtIG1heChwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpzYWxfc3VyZmFjZV9taW4gPC0gbWluKHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21lYW4gPC0gbWVhbihwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KQ2hsDQpgYGB7cn0NCmNobF9kZXB0aF9tYXggPC0gbWF4KHByZXNlbmNlJGNobF9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KY2hsX2RlcHRoX21pbiA8LSBtaW4ocHJlc2VuY2UkY2hsX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpjaGxfZGVwdGhfbWVhbiA8LSBtZWFuKHByZXNlbmNlJGNobF9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWF4IDwtIG1heChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWluIDwtIG1pbihwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJGNobF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KTzINCmBgYHtyfQ0KbzJfZGVwdGhfbWF4IDwtIG1heChwcmVzZW5jZSRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfZGVwdGhfbWluIDwtIG1pbihwcmVzZW5jZSRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfZGVwdGhfbWVhbiA8LSBtZWFuKHByZXNlbmNlJG8yX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpvMl9zdXJmYWNlX21heCA8LSBtYXgocHJlc2VuY2UkbzJfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbzJfc3VyZmFjZV9taW4gPC0gbWluKHByZXNlbmNlJG8yX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCm8yX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJG8yX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpNTFANCmBgYHtyfQ0KbWxwX3N1cmZhY2VfbWF4IDwtIG1heChwcmVzZW5jZSRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbWxwX3N1cmZhY2VfbWluIDwtIG1pbihwcmVzZW5jZSRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbWxwX3N1cmZhY2VfbWVhbiA8LSBtZWFuKHByZXNlbmNlJG1scF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KU1NIDQpgYGB7cn0NCnNzaF9zdXJmYWNlX21heCA8LSBtYXgocHJlc2VuY2Ukc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNzaF9zdXJmYWNlX21pbiA8LSBtaW4ocHJlc2VuY2Ukc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNzaF9zdXJmYWNlX21lYW4gPC0gbWVhbihwcmVzZW5jZSRzc2hfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNCmNyZWF0ZSBtYXRyaXgNCmBgYHtyfQ0KdGQgPC0gYyh0ZW1wX2RlcHRoX21heCwgdGVtcF9kZXB0aF9taW4sIHRlbXBfZGVwdGhfbWVhbikNCnRzIDwtIGModGVtcF9zdXJmYWNlX21heCwgdGVtcF9zdXJmYWNlX21pbiwgdGVtcF9zdXJmYWNlX21lYW4pDQpzZCA8LSBjKHNhbF9kZXB0aF9tYXgsIHNhbF9kZXB0aF9taW4sIHNhbF9kZXB0aF9tZWFuKQ0Kc3MgPC0gYyhzYWxfc3VyZmFjZV9tYXgsIHNhbF9zdXJmYWNlX21pbiwgc2FsX3N1cmZhY2VfbWVhbikNCmNkIDwtIGMoc2FsX2RlcHRoX21heCwgc2FsX2RlcHRoX21pbiwgc2FsX2RlcHRoX21lYW4pDQpjcyA8LSBjKHNhbF9zdXJmYWNlX21heCwgc2FsX3N1cmZhY2VfbWluLCBzYWxfc3VyZmFjZV9tZWFuKQ0Kb2QgPC0gYyhvMl9kZXB0aF9tYXgsIG8yX2RlcHRoX21pbiwgbzJfZGVwdGhfbWVhbikNCm9zIDwtIGMobzJfc3VyZmFjZV9tYXgsIG8yX3N1cmZhY2VfbWluLCBvMl9zdXJmYWNlX21lYW4pDQptbHAgPC0gYyhtbHBfc3VyZmFjZV9tYXgsIG1scF9zdXJmYWNlX21pbiwgbWxwX3N1cmZhY2VfbWVhbikNCnNzaCA8LSBjKHNzaF9zdXJmYWNlX21heCwgc3NoX3N1cmZhY2VfbWluLCBzc2hfc3VyZmFjZV9tZWFuKQ0KZW52X3N0YXRzIDwtIHJiaW5kKHRkLCB0cywgc2QsIHNzLCBjZCwgY3MsIG9kLCBvcywgbWxwLCBzc2gpDQpyb3cubmFtZXMoZW52X3N0YXRzKSA8LSBjKCJUZW1wIERlcHRoIiwgIlRlbXAgU3VyZmFjZSIsICJTYWxpbml0eSBEZXB0aCIsICJTYWxpbml0eSBTdXJmYWNlIiwgIkNobCBEZXB0aCIsICJDaGwgU3VyZmFjZSIsICJPeHlnZW4gRGVwdGgiLCAiT3h5Z2VuIFN1cmZhY2UiLCAiTUxQIiwgIlNTSCIpIA0KY29sbmFtZXMoZW52X3N0YXRzKSA8LSBjKCJNYXgiLCAiTWluIiwgIk1lYW4iKQ0Kd3JpdGUuY3N2KGVudl9zdGF0cywgIi4uL291dHB1dC9lbnYvZW52X2NvcnJlbGF0ZXNfYmFzaWNfc3RhdHMuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCmVudl9zdGF0cw0KYGBgDQoNCkhtbSBzb21lIHBvdGVudGlhbGx5IHN1c3BpY2lvdXMgdmFsdWVzIGhlcmUgaW4NCi0gT3h5Z2VuIERlcHRoIG1pbg0KLSBtbHAgIE1heA0KYW5kIG1heWJlIGFsc28NCi0gU2FsaW5pdHkgRGVwdGggbWluDQotIFNhbGluaXR5IFN1cmZhY2UgbWluDQotIENITCBkZXB0aCBtaW4NCi0gQ0hMIGRlcHRoIG1heA0KDQpsZXRzIGp1c3Qgc2VlIHdoZXJlIHRoZXNlIHZhbHVlcyBhcHBlYXIgYW5kIGNoZWNrIHRoZSBuZXRjZGYgbGF5ZXJzLiBOb3RlIEkgd2lsbCBjaGVjayB0aGVzZSB2YWx1ZXMgaW4gY3lnd2luIHVzaW5nIHRoZSBjZG8gb3BlcmF0b3IgaW5mb3Ygb24gdGhlIG5ldGNkZnMgKHRvIGVuc3VyZSB0aGVyZSB3YXMgbm8gaXNzdWUgd2l0aCBwcm9jZXNzaW5nIGluIFIpLiANCg0KDQpnZXQgdGhlIHllYXIgYW5kIG1vbnRoIHRoZXNlIHZhbHVlcyBhcHBlYXJlZCBpbg0KYGBge3J9DQpvMmRfY2hlY2tfeXIgPC0gc3Vic2V0KHByZXNlbmNlJHllYXIsIHByZXNlbmNlJG8yX2RlcHRoID09IG8yX2RlcHRoX21pbikNCm8yZF9jaGVja19tdGggPC0gc3Vic2V0KHByZXNlbmNlJG1vbnRoLCBwcmVzZW5jZSRvMl9kZXB0aCA9PSBvMl9kZXB0aF9taW4pDQpgYGANCk8yIGRlcHRoIG1pbiBpcyBpbiAyMDA1XzA4DQoNCkFuZCB2YWx1ZSBzZWVtcyBjb3JyZWN0DQoNCmBgYHtyfQ0KbWxwX2NoZWNrX3lyIDwtIHN1YnNldChwcmVzZW5jZSR5ZWFyLCBwcmVzZW5jZSRtbHBfc3VyZmFjZSA9PSBtbHBfc3VyZmFjZV9tYXgpDQptbHBfY2hlY2tfbXRoIDwtIHN1YnNldChwcmVzZW5jZSRtb250aCwgcHJlc2VuY2UkbWxwX3N1cmZhY2UgPT0gbWxwX3N1cmZhY2VfbWF4KQ0KYGBgDQptbHAgbWF4IGluIGluIDIwMDdfMTINCg0KQW5kIHllcyB0aGUgdmFsdWUgc2VlbXMgY29ycmVjdA0KDQpgYGB7cn0NCnNhbGRfY2hlY2tfeXIgPC0gc3Vic2V0KHByZXNlbmNlJHllYXIsIHByZXNlbmNlJHNhbGluaXR5X2RlcHRoID09IHNhbF9kZXB0aF9tYXgpDQpzYWxkX2NoZWNrX210aCA8LSBzdWJzZXQocHJlc2VuY2UkbW9udGgsIHByZXNlbmNlJHNhbGluaXR5X2RlcHRoID09IHNhbF9kZXB0aF9tYXgpDQpgYGANCnllYXIgbW9udGggMjAwMV8wNQ0KDQphbHNvIHNlZW1zIGNvcnJlY3QNCg0KYGBge3J9DQpzYWxzX2NoZWNrX3lyIDwtIHN1YnNldChwcmVzZW5jZSR5ZWFyLCBwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlID09IHNhbF9zdXJmYWNlX21pbikNCnNhbHNfY2hlY2tfbXRoIDwtIHN1YnNldChwcmVzZW5jZSRtb250aCwgcHJlc2VuY2Ukc2FsaW5pdHlfc3VyZmFjZSA9PSBzYWxfc3VyZmFjZV9taW4pDQpgYGANCnllYXIgbW9udGggMjE5OThfMDYNCg0Kb2sgYWdhaW4uLi4NCg0KTGVhdmUgdGhlIHJlc3QNCg0KDQojIyBzaW1wbGUgcGxvdHMgb2YgZW52LiBjb3JyZWxhdGVzDQoNCnRlbXBlcmF0dXJlDQpgYGB7cn0NCnBhcihtZnJvdz1jKDEsMikpDQpwbG90KHByZXNlbmNlJHRlbXBfZGVwdGgsIG1haW4gPSAiVGVtcCBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIktlbHZpbiIpDQpwbG90KHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbWFpbiA9ICJUZW1wIGF0IFN1cmZhY2UiLCB5bGFiID0gIktlbHZpbiIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQpIbW0gbm90IG5lY2Vzc2FyaWx5IHZlcnkgaGVscGZ1bC4gQnV0IGFueXdheSwgbGV0cyBjYXJyeSBvbg0KDQpzYWxpbml0eQ0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KcGxvdChwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbWFpbiA9ICJTYWxpbml0eSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIlByYWN0aWNhbCBTYWxpbml0eSBVbml0cyIpDQpwbG90KHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UsIG1haW4gPSAiU2FsaW5pdHkgYXQgU3VyZmFjZSIsIHlsYWIgPSAiUHJhY3RpY2FsIFNhbGluaXR5IFVuaXRzIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc2FsaW5pdHlfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpDaGxvcm9waHlsbA0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KcGxvdChwcmVzZW5jZSRjaGxfZGVwdGgsIG1haW4gPSAiQ2hsIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbWFpbiA9ICJDaGwgYXQgU3VyZmFjZSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpPMg0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KcGxvdChwcmVzZW5jZSRvMl9kZXB0aCwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChwcmVzZW5jZSRvMl9zdXJmYWNlLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgU3VyZmFjZSIsIHlsYWIgPSAiTzIgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX3NpbXBsZXBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KbWxwDQpgYGB7cn0NCnBsb3QocHJlc2VuY2UkbWxwX3N1cmZhY2UsIG1haW4gPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIiwgeWxhYiA9ICJEZXB0aCAobSkiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpTU0gNCmBgYHtyfQ0KcGxvdChwcmVzZW5jZSRzc2hfc3VyZmFjZSwgbWFpbiA9ICJTZWEgU3VyZmFjZSBIZWlnaHQiLCB5bGFiID0gIkhlaWdodCAobSkiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpYWFggU0FNIC0gWU9VIFdBTlQgVE8gVEhJTksgQUJPVVQgRE9JTkcgVEhJUyBCWSBERVBUSCBSQVRIRVIgVEhBTiBBTEwgREVQVEhTKQ0KDQpgYGB7cn0NCnVuaXF1ZV9kZXB0aHMgPC0gdW5pcXVlKHByZXNlbmNlJGRlcHRobGF5ZXJubykNCnVuaXF1ZV9kZXB0aGRvcmRlcmVkIDwtIHNvcnQodW5pcXVlX2RlcHRocykgI2p1c3QgcHV0cyB0aGUgbGlzdCBpbiBvZGVyIHdpdGggbm8gTkENCmxlbmd0aCh1bmlxdWVfZGVwdGhkb3JkZXJlZCkNCmBgYA0Kb3VjaCAtIDM5IGxheWVycy4uLiBhIGpvYiBmb3IgYSBib3hwbG90IHByb2JhYmx5DQoNCmBgYHtyfQ0KDQpgYGANCg0KDQoNCiMgZnJlcXVlbmN5IHBsb3RzIG9mIGVudi4gY29ycg0KDQoNCnRlbXBlcmF0dXJlDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkdGVtcF9zdXJmYWNlLCBtYWluID0gIlRlbXAgYXQgU3VyZmFjZSIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSR0ZW1wX2RlcHQsIG1haW4gPSAiVGVtcCBhdCBEZXB0aCIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpjaGwNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbWFpbiA9ICJDaGxvcm9waHlsbCBhdCBTdXJmYWNlIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkY2hsX2RlcHRoLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9kZXB0aF9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0Kc2FsaW5pdHkNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSRzYWxpbml0eV9zdXJmYWNlLCBtYWluID0gIlNhbGluaXR5IGF0IFN1cmZhY2UiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmhpc3QocHJlc2VuY2Ukc2FsaW5pdHlfZGVwdGgsIG1haW4gPSAiU2FsaW5pdHkgYXQgT2JzZXJ2YXRpb24gRGVwdGgiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9kZXB0aF9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0Kb3h5Z2VuDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkbzJfc3VyZmFjZSwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IFN1cmZhY2UiLCB4bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChwcmVzZW5jZSRvMl9kZXB0aCwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9vMl9kZXB0aF9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KTUxQDQpgYGB7cn0NCmhpc3QocHJlc2VuY2UkbWxwLCBtYWluID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0Kc3NoDQpgYGB7cn0NCmhpc3QocHJlc2VuY2Ukc3NoLCBtYWluID0gIlNlYSBTdXJmYWNlIEhlaWdodCBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KDQojIyBzaW1wbGUgYm94cGxvdHMgb2YgZW52LiBjb3JyDQoNClNhbWUgYXMgYWJvdmUgYnV0IHdpdGggYm94cGxvdHMgKG1heSBwcm92aWRlIHNvbWUgbW9yZSB1c2VmdWwgaW5mbykNCg0KDQoNCmluZGl2aWR1YWwgcGxvdHMgb2YgZWFjaCB2YXJpYWJsZSANCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCmJveHBsb3QocHJlc2VuY2UkdGVtcF9kZXB0aCwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIktlbHZpbiIpDQpib3hwbG90KHByZXNlbmNlJHRlbXBfc3VyZmFjZSwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBTdXJmYWNlIiwgeWxhYiA9ICJLZWx2aW4iKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcF9ib3hwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpwYXIobWZyb3c9YygxLDIpKQ0KYm94cGxvdChwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCwgbWFpbiA9ICJTYWxpbml0eSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIlBTVSIpDQpib3hwbG90KHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UsIG1haW4gPSAiU2FsaW5pdHkgYXQgU3VyZmFjZSIsIHlsYWIgPSAiUFNVIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JveHBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCnBhcihtZnJvdz1jKDEsMikpDQpib3hwbG90KHByZXNlbmNlJG8yX2RlcHRoLCBtYWluID0gIk8yIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAibW1vbC5tLTMiKQ0KYm94cGxvdChwcmVzZW5jZSRvMl9zdXJmYWNlLCBtYWluID0gIk8yIGF0IFN1cmZhY2UiLCB5bGFiID0gIm1tb2wubS0zIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2JveHBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCnBhcihtZnJvdz1jKDEsMikpDQpib3hwbG90KHByZXNlbmNlJGNobF9kZXB0aCwgbWFpbiA9ICJDaGxvcnBoeWxsIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAibW1vbC5tLTMiKQ0KYm94cGxvdChwcmVzZW5jZSRjaGxfc3VyZmFjZSwgbWFpbiA9ICJDaGxvcnBoeWxsIGF0IFN1cmZhY2UiLCB5bGFiID0gIm1tb2wubS0zIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9ib3hwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpwYXIobWZyb3c9YygxLDIpKQ0KYm94cGxvdChwcmVzZW5jZSRtbHBfc3VyZmFjZSwgbWFpbiA9ICJEZW5zaXR5IE1peGVkIExheWVyIFRoaWNrbmVzcyIsIHlsYWIgPSAibWV0ZXJzIikNCmJveHBsb3QocHJlc2VuY2Ukc3NoX3N1cmZhY2UsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IiwgeWxhYiA9ICJtZXRlcnMiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX3NzaF9ib3hwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSR0ZW1wX2RlcHRoIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiBEZXB0aCBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcGVyYXR1cmVfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRjaGxfZGVwdGggfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobG9yb3BoeWxsX2JveHBsb3RfZGVwdF9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2Ukc2FsaW5pdHlfZGVwdGggfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9ib3hwbG90X2RlcHRfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJG8yX2RlcHRoIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIiwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9vMl9ib3hwbG90X2RlcHRfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJG1scF9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyAobSkiLCBtYWluID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX2JveHBsb3RfZGVwdF9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2Ukc3NoX3N1cmZhY2UgfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IE9ic2VydmF0aW9uIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSR0ZW1wX2RlcHRoIH4gcHJlc2VuY2UkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJUZW1wZXJhdHVyZSAoS2VsdmluKSIsIG1haW4gPSAiVGVtcGVyYXR1cmUgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcGVyYXR1cmVfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJGNobF9kZXB0aCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvY2hsX2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRzYWxpbml0eV9kZXB0aCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRvMl9kZXB0aCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgT2JzZXJ2YXRpb24gRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvb3h5Z2VuX2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRtbHAgfiBwcmVzZW5jZSR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyAobSkiLCBtYWluID0gIk1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJHNzaCB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IE9ic2VydmF0aW9uIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NzaF9ib3hwbG90X2RlcHRfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkdGVtcF9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiAoU3VyZmFjZSkgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkY2hsX3N1cmZhY2UgfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxvcm9waHlsbF9ib3hwbG90X3N1cmZhY2VfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJHNhbGluaXR5X3N1cmZhY2UgfiBwcmVzZW5jZSRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIChTdXJmYWNlKSBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc2FsaW5pdHlfYm94cGxvdF9zdXJmYWNlX21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRvMl9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIiwgbWFpbiA9ICJEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIChTdXJmYWNlKSBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfYm94cGxvdF9zdXJmYWNlX21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRtbHBfc3VyZmFjZSB+IHByZXNlbmNlJG1vbnRoLCB4bGFiID0gIm1vbnRoIiwgeWxhYiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgKG0pIiwgbWFpbiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgYXQgT2JzZXJ2YXRpb24gcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL21scF9ib3hwbG90X3N1cmZhY2VfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KHByZXNlbmNlJHNzaF9zdXJmYWNlIH4gcHJlc2VuY2UkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlNlYSBTdXJmYWNlIEhlaWdodCAobSkiLCBtYWluID0gIlNlYSBTdXJmYWNlIEhlaWdodCBhdCBPYnNlcnZhdGlvbiBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkdGVtcF9zdXJmYWNlIH4gcHJlc2VuY2UkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJUZW1wZXJhdHVyZSAoS2VsdmluKSIsIG1haW4gPSAiVGVtcGVyYXR1cmUgYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JveHBsb3Rfc3VyZmFjZV95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChwcmVzZW5jZSRjaGxfc3VyZmFjZSB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiQ2hsb3JvcGh5bGwgQ29uY2VudHJhdGlvbnMgKG1tb2wubS0zKSIsIG1haW4gPSAiQ2hsb3JvcGh5bGwgYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2Ukc2FsaW5pdHlfc3VyZmFjZSB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IE9ic2VydmF0aW9uIChTdXJmYWNlKSBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QocHJlc2VuY2UkbzJfc3VyZmFjZSB+IHByZXNlbmNlJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgT2JzZXJ2YXRpb24gKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL294eWdlbl9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQoNCiMgYmFja2dyb3VuZCBwb2ludHMNCg0KDQojIGVudmlyb25tZW50YWwgY29ycmVsYXRlcw0KDQoxKSBHZXQgdGhlIG1heCwgbWluLCBhbiBtZWFuIHZhbHVlcyBhbmQgYWRkIGludG8gYSBkYXRhZnJhbWUNCg0KVGVtcGVyYXR1cmUNCmBgYHtyfQ0KdGVtcF9kZXB0aF9tYXhfYmFjayA8LSBtYXgoYmFja2dyb3VuZCR0ZW1wX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX2RlcHRoX21pbl9iYWNrIDwtIG1pbihiYWNrZ3JvdW5kJHRlbXBfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnRlbXBfZGVwdGhfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCR0ZW1wX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWF4X2JhY2sgPC0gbWF4KGJhY2tncm91bmQkdGVtcF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWluX2JhY2sgPC0gbWluKGJhY2tncm91bmQkdGVtcF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQp0ZW1wX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCR0ZW1wX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpTYWxpbml0eQ0KYGBge3J9DQpzYWxfZGVwdGhfbWF4X2JhY2sgPC0gbWF4KGJhY2tncm91bmQkc2FsaW5pdHlfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnNhbF9kZXB0aF9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRzYWxpbml0eV9kZXB0aCwgbmEucm0gPSBUUlVFKQ0Kc2FsX2RlcHRoX21lYW5fYmFjayA8LSBtZWFuKGJhY2tncm91bmQkc2FsaW5pdHlfZGVwdGgsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJHNhbGluaXR5X3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21pbl9iYWNrIDwtIG1pbihiYWNrZ3JvdW5kJHNhbGluaXR5X3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNhbF9zdXJmYWNlX21lYW5fYmFjayA8LSBtZWFuKGJhY2tncm91bmQkc2FsaW5pdHlfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNCkNobA0KYGBge3J9DQpjaGxfZGVwdGhfbWF4X2JhY2sgPC0gbWF4KGJhY2tncm91bmQkY2hsX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpjaGxfZGVwdGhfbWluX2JhY2sgPC0gbWluKGJhY2tncm91bmQkY2hsX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpjaGxfZGVwdGhfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRjaGxfZGVwdGgsIG5hLnJtID0gVFJVRSkNCmNobF9zdXJmYWNlX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJGNobF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpjaGxfc3VyZmFjZV9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KY2hsX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRjaGxfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNCk8yDQpgYGB7cn0NCm8yX2RlcHRoX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJG8yX2RlcHRoLCBuYS5ybSA9IFRSVUUpDQpvMl9kZXB0aF9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfZGVwdGhfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRvMl9kZXB0aCwgbmEucm0gPSBUUlVFKQ0KbzJfc3VyZmFjZV9tYXhfYmFjayA8LSBtYXgoYmFja2dyb3VuZCRvMl9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpvMl9zdXJmYWNlX21pbl9iYWNrIDwtIG1pbihiYWNrZ3JvdW5kJG8yX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCm8yX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRvMl9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQpgYGANCg0KTUxQDQpgYGB7cn0NCm1scF9zdXJmYWNlX21heF9iYWNrIDwtIG1heChiYWNrZ3JvdW5kJG1scF9zdXJmYWNlLCBuYS5ybSA9IFRSVUUpDQptbHBfc3VyZmFjZV9taW5fYmFjayA8LSBtaW4oYmFja2dyb3VuZCRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KbWxwX3N1cmZhY2VfbWVhbl9iYWNrIDwtIG1lYW4oYmFja2dyb3VuZCRtbHBfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNClNTSA0KYGBge3J9DQpzc2hfc3VyZmFjZV9tYXhfYmFjayA8LSBtYXgoYmFja2dyb3VuZCRzc2hfc3VyZmFjZSwgbmEucm0gPSBUUlVFKQ0Kc3NoX3N1cmZhY2VfbWluX2JhY2sgPC0gbWluKGJhY2tncm91bmQkc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCnNzaF9zdXJmYWNlX21lYW5fYmFjayA8LSBtZWFuKGJhY2tncm91bmQkc3NoX3N1cmZhY2UsIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpjcmVhdGUgbWF0cml4DQpgYGB7cn0NCnRkYiA8LSBjKHRlbXBfZGVwdGhfbWF4X2JhY2ssIHRlbXBfZGVwdGhfbWluX2JhY2ssIHRlbXBfZGVwdGhfbWVhbl9iYWNrKQ0KdHNiIDwtIGModGVtcF9zdXJmYWNlX21heF9iYWNrLCB0ZW1wX3N1cmZhY2VfbWluX2JhY2ssIHRlbXBfc3VyZmFjZV9tZWFuX2JhY2spDQpzZGIgPC0gYyhzYWxfZGVwdGhfbWF4X2JhY2ssIHNhbF9kZXB0aF9taW5fYmFjaywgc2FsX2RlcHRoX21lYW5fYmFjaykNCnNzYiA8LSBjKHNhbF9zdXJmYWNlX21heF9iYWNrLCBzYWxfc3VyZmFjZV9taW5fYmFjaywgc2FsX3N1cmZhY2VfbWVhbl9iYWNrKQ0KY2RiIDwtIGMoc2FsX2RlcHRoX21heF9iYWNrLCBzYWxfZGVwdGhfbWluX2JhY2ssIHNhbF9kZXB0aF9tZWFuX2JhY2spDQpjc2IgPC0gYyhzYWxfc3VyZmFjZV9tYXhfYmFjaywgc2FsX3N1cmZhY2VfbWluX2JhY2ssIHNhbF9zdXJmYWNlX21lYW5fYmFjaykNCm9kYiA8LSBjKG8yX2RlcHRoX21heF9iYWNrLCBvMl9kZXB0aF9taW5fYmFjaywgbzJfZGVwdGhfbWVhbl9iYWNrKQ0Kb3NiIDwtIGMobzJfc3VyZmFjZV9tYXhfYmFjaywgbzJfc3VyZmFjZV9taW5fYmFjaywgbzJfc3VyZmFjZV9tZWFuX2JhY2spDQptbHBiIDwtIGMobWxwX3N1cmZhY2VfbWF4X2JhY2ssIG1scF9zdXJmYWNlX21pbl9iYWNrLCBtbHBfc3VyZmFjZV9tZWFuX2JhY2spDQpzc2hiIDwtIGMoc3NoX3N1cmZhY2VfbWF4X2JhY2ssIHNzaF9zdXJmYWNlX21pbl9iYWNrLCBzc2hfc3VyZmFjZV9tZWFuX2JhY2spDQplbnZfc3RhdHNfYmFjayA8LSByYmluZCh0ZGIsIHRzYiwgc2RiLCBzc2IsIGNkYiwgY3NiLCBvZGIsIG9zYiwgbWxwYiwgc3NoYikNCnJvdy5uYW1lcyhlbnZfc3RhdHNfYmFjaykgPC0gYygiVGVtcCBEZXB0aCIsICJUZW1wIFN1cmZhY2UiLCAiU2FsaW5pdHkgRGVwdGgiLCAiU2FsaW5pdHkgU3VyZmFjZSIsICJDaGwgRGVwdGgiLCAiQ2hsIFN1cmZhY2UiLCAiT3h5Z2VuIERlcHRoIiwgIk94eWdlbiBTdXJmYWNlIiwgIk1MUCIsICJTU0giKSANCmNvbG5hbWVzKGVudl9zdGF0c19iYWNrKSA8LSBjKCJNYXgiLCAiTWluIiwgIk1lYW4iKQ0Kd3JpdGUuY3N2KGVudl9zdGF0c19iYWNrLCAiLi4vb3V0cHV0L2Vudi9lbnZfY29ycmVsYXRlc19iYWNrZ3JvdW5kX2Jhc2ljX3N0YXRzLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQplbnZfc3RhdHNfYmFjaw0KYGBgDQoNCnRlbXBlcmF0dXJlDQpgYGB7cn0NCnBhcihtZnJvdz1jKDEsMikpDQpwbG90KGJhY2tncm91bmQkdGVtcF9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBUZW1wIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiS2VsdmluIikNCnBsb3QoYmFja2dyb3VuZCR0ZW1wX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgVGVtcCBhdCBTdXJmYWNlIiwgeWxhYiA9ICJLZWx2aW4iKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcGVyYXR1cmVfYmFja2dyb3VuZF9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCg0Kc2FsaW5pdHkNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QoYmFja2dyb3VuZCRzYWxpbml0eV9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBTYWxpbml0eSBhdCBEZXB0aCAoVmFyaW91cykiLCB5bGFiID0gIlByYWN0aWNhbCBTYWxpbml0eSBVbml0cyIpDQpwbG90KGJhY2tncm91bmQkc2FsaW5pdHlfc3VyZmFjZSwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBTYWxpbml0eSBhdCBTdXJmYWNlIiwgeWxhYiA9ICJQcmFjdGljYWwgU2FsaW5pdHkgVW5pdHMiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9iYWNrZ3JvdW5kX3NpbXBsZXBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KQ2hsb3JvcGh5bGwNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QoYmFja2dyb3VuZCRjaGxfZGVwdGgsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgQ2hsIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChiYWNrZ3JvdW5kJGNobF9zdXJmYWNlLCBtYWluID0gIkJhY2tncm91bmQgUG9pbnRzIENobCBhdCBTdXJmYWNlIiwgeWxhYiA9ICJDaGwgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX3NpbXBsZXBsb3QucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KTzINCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QoYmFja2dyb3VuZCRvMl9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFBvaW50cyBEaXNzb2x2ZWQgT3h5Z2VuIGF0IERlcHRoIChWYXJpb3VzKSIsIHlsYWIgPSAiQ2hsIChtbW9sLm0tMykiKQ0KcGxvdChiYWNrZ3JvdW5kJG8yX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgRGlzc29sdmVkIE94eWdlbiBhdCBTdXJmYWNlIiwgeWxhYiA9ICJPMiAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfYmFja2dyb3VuZF9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCm1scA0KYGBge3J9DQpwbG90KGJhY2tncm91bmQkbWxwX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIiwgeWxhYiA9ICJEZXB0aCAobSkiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYmFja2dyb3VuZF9zaW1wbGVwbG90LnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNClNTSA0KYGBge3J9DQpwbG90KGJhY2tncm91bmQkc3NoX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBQb2ludHMgU2VhIFN1cmZhY2UgSGVpZ2h0IiwgeWxhYiA9ICJIZWlnaHQgKG0pIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JhY2tncm91bmRfc2ltcGxlcGxvdC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQojIyBmcmVxdWVuY3kgcGxvdHMgb2YgZW52LiBjb3JyDQoNCg0KdGVtcGVyYXR1cmUNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJHRlbXBfc3VyZmFjZSwgbWFpbiA9ICJCYWNrZ3JvdW5kIFRlbXAgYXQgU3VyZmFjZSIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkdGVtcF9kZXB0LCBtYWluID0gIkJhY2tncm91bmQgVGVtcCBhdCBEZXB0aCIsIHhsYWIgPSAiS2VsdmluIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfZGVwdGhfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmNobA0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkY2hsX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBDaGxvcm9waHlsbCBhdCBTdXJmYWNlIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJGNobF9kZXB0aCwgbWFpbiA9ICJCYWNrZ3JvdW5kIENobG9yb3BoeWxsIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJDaGxvcm9waHlsbCBDb25jZW50cmF0aW9ucyAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpzYWxpbml0eQ0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkc2FsaW5pdHlfc3VyZmFjZSwgbWFpbiA9ICJCYWNrZ3JvdW5kIFNhbGluaXR5IGF0IFN1cmZhY2UiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9iYWNrZ3JvdW5kX3N1cmZhY2VfaGlzdG9ncmFtLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJHNhbGluaXR5X2RlcHRoLCBtYWluID0gIkJhY2tncm91bmQgU2FsaW5pdHkgYXQgT2JzZXJ2YXRpb24gRGVwdGgiLCB4bGFiID0gIlNhbGluaXR5IFByYWN0aWNhbCBTYWxpbml0eSBVbml0IChQU1UpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbF9iYWNrZ3JvdW5kX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpveHlnZW4NCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJG8yX3N1cmZhY2UsIG1haW4gPSAiQmFja2dyb3VuZCBEaXNzb2x2ZWQgT3h5Z2VuIGF0IFN1cmZhY2UiLCB4bGFiID0gIk1vbGUgQ29uY2VudHJhdGlvbiBvZiBEaXNzb2x2ZWQgT3h5Z2VuIGluIFNlYSBXYXRlciAobW1vbC5tLTMpIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2JhY2tncm91bmRfc3VyZmFjZV9oaXN0b2dyYW0ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpoaXN0KGJhY2tncm91bmQkbzJfZGVwdGgsIG1haW4gPSAiQmFja2dyb3VuZCBEaXNzb2x2ZWQgT3h5Z2VuIGF0IE9ic2VydmF0aW9uIERlcHRoIiwgeGxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9vMl9iYWNrZ3JvdW5kX2RlcHRoX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpNTFANCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJG1scCwgbWFpbiA9ICJCYWNrZ3JvdW5kIE1peGVkIExheWVyIFRoaWNrbmVzcyBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYmFja2dyb3VuZF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpzc2gNCmBgYHtyfQ0KaGlzdChiYWNrZ3JvdW5kJHNzaCwgbWFpbiA9ICJCYWNrZ3JvdW5kIFNlYSBTdXJmYWNlIEhlaWdodCBhdCBPYnNlcnZhdGlvbiIsIHhsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfYmFja2dyb3VuZF9zdXJmYWNlX2hpc3RvZ3JhbS5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQojIyBzaW1wbGUgYm94cGxvdHMgb2YgZW52LiBjb3JyDQoNClNhbWUgYXMgYWJvdmUgYnV0IHdpdGggYm94cGxvdHMgKG1heSBwcm92aWRlIHNvbWUgbW9yZSB1c2VmdWwgaW5mbykNCg0KdGVtcGVyYXR1cmUNCg0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCR0ZW1wX2RlcHRoIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiVGVtcGVyYXR1cmUgKEtlbHZpbikiLCBtYWluID0gIlRlbXBlcmF0dXJlIGF0IEJhY2tncm91bmQgRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJGNobF9kZXB0aCB+IGJhY2tncm91bmQkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobG9yb3BoeWxsX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJHNhbGluaXR5X2RlcHRoIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgRGVwdGggcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJG8yX2RlcHRoIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgQmFja2dyb3VuZCBEZXB0aCBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfYmFja2dyb3VuZF9ib3hwbG90X2RlcHRfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkbWxwX3N1cmZhY2UgfiBiYWNrZ3JvdW5kJG1vbnRoLCB4bGFiID0gIm1vbnRoIiwgeWxhYiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgKG0pIiwgbWFpbiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgYXQgQmFja2dyb3VuZCBwZXIgTW9udGgiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJHNzaF9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IEJhY2tncm91bmQgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NzaF9iYWNrZ3JvdW5kX2JveHBsb3RfZGVwdF9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCR0ZW1wX2RlcHRoIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBCYWNrZ3JvdW5kIERlcHRoIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3RlbXBlcmF0dXJlX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkY2hsX2RlcHRoIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvY2hsX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkc2FsaW5pdHlfZGVwdGggfiBiYWNrZ3JvdW5kJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgRGVwdGggcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc2FsaW5pdHlfYmFja2dyb3VuZF9ib3hwbG90X2RlcHRfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRvMl9kZXB0aCB+IGJhY2tncm91bmQkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIsIG1haW4gPSAiRGlzc29sdmVkIE94eWdlbiBhdCBCYWNrZ3JvdW5kIERlcHRoIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL294eWdlbl9iYWNrZ3JvdW5kX2JveHBsb3RfZGVwdF95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJG1scCB+IGJhY2tncm91bmQkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgKG0pIiwgbWFpbiA9ICJNaXhlZCBMYXllciBUaGlja25lc3MgYXQgQmFja2dyb3VuZCBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9tbHBfYmFja2dyb3VuZF9ib3hwbG90X2RlcHRfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRzc2ggfiBiYWNrZ3JvdW5kJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IChtKSIsIG1haW4gPSAiU2VhIFN1cmZhY2UgSGVpZ2h0IGF0IEJhY2tncm91bmQgcGVyIFllYXIiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JhY2tncm91bmRfYm94cGxvdF9kZXB0X3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkdGVtcF9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiVGVtcGVyYXR1cmUgKEtlbHZpbikiLCBtYWluID0gIlRlbXBlcmF0dXJlIGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRjaGxfc3VyZmFjZSB+IGJhY2tncm91bmQkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxvcm9waHlsbF9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRzYWxpbml0eV9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRvMl9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiTW9sZSBDb25jZW50cmF0aW9uIG9mIERpc3NvbHZlZCBPeHlnZW4gaW4gU2VhIFdhdGVyIChtbW9sLm0tMykiLCBtYWluID0gIkRpc3NvbHZlZCBPeHlnZW4gYXQgQmFja2dyb3VuZCAoU3VyZmFjZSkgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2JhY2tncm91bmRfYm94cGxvdF9zdXJmYWNlX21vbnRoLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJG1scF9zdXJmYWNlIH4gYmFja2dyb3VuZCRtb250aCwgeGxhYiA9ICJtb250aCIsIHlsYWIgPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIChtKSIsIG1haW4gPSAiTWl4ZWQgTGF5ZXIgVGhpY2tuZXNzIGF0IEJhY2tncm91bmQgcGVyIE1vbnRoIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL21scF9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV9tb250aC5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoYmFja2dyb3VuZCRzc2hfc3VyZmFjZSB+IGJhY2tncm91bmQkbW9udGgsIHhsYWIgPSAibW9udGgiLCB5bGFiID0gIlNlYSBTdXJmYWNlIEhlaWdodCAobSkiLCBtYWluID0gIlNlYSBTdXJmYWNlIEhlaWdodCBhdCBCYWNrZ3JvdW5kIHBlciBNb250aCIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zc2hfYmFja2dyb3VuZF9ib3hwbG90X3N1cmZhY2VfbW9udGgucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkdGVtcF9zdXJmYWNlIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBCYWNrZ3JvdW5kIChTdXJmYWNlKSBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJGNobF9zdXJmYWNlIH4gYmFja2dyb3VuZCR5ZWFyLCB4bGFiID0gIlllYXIiLCB5bGFiID0gIkNobG9yb3BoeWxsIENvbmNlbnRyYXRpb25zIChtbW9sLm0tMykiLCBtYWluID0gIkNobG9yb3BoeWxsIGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL2NobF9iYWNrZ3JvdW5kX2JveHBsb3Rfc3VyZmFjZV95ZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChiYWNrZ3JvdW5kJHNhbGluaXR5X3N1cmZhY2UgfiBiYWNrZ3JvdW5kJHllYXIsIHhsYWIgPSAiWWVhciIsIHlsYWIgPSAiU2FsaW5pdHkgUHJhY3RpY2FsIFNhbGluaXR5IFVuaXQgKFBTVSkiLCBtYWluID0gIlNhbGluaXR5IGF0IEJhY2tncm91bmQgKFN1cmZhY2UpIHBlciBZZWFyIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X2JhY2tncm91bmRfYm94cGxvdF9zdXJmYWNlX3llYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpib3hwbG90KGJhY2tncm91bmQkbzJfc3VyZmFjZSB+IGJhY2tncm91bmQkeWVhciwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJNb2xlIENvbmNlbnRyYXRpb24gb2YgRGlzc29sdmVkIE94eWdlbiBpbiBTZWEgV2F0ZXIgKG1tb2wubS0zKSIsIG1haW4gPSAiRGlzc29sdmVkIE94eWdlbiBhdCBCYWNrZ3JvdW5kIChTdXJmYWNlKSBwZXIgWWVhciIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9veHlnZW5fYmFja2dyb3VuZF9ib3hwbG90X3N1cmZhY2VfeWVhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQojIyBjb3JyZWxhdGlvbnMgYmV0d2VlbiBiYWNrZ3JvdW5kIHBvaW50cw0KDQpjaGVjayB0byBzZWUgaWYgdGhlcmUgYXJlIGFueSBjb3JyZWxhdGlvbnMgaW4gdGhlIGVudi4gdmFyaWFibGVzIGZvciB0aGUgYmFja2dyb3VuZCBwb2ludHMNCg0KDQpmaXJzdCBzdWJzZXQgdGhlIGVudi5jb3JyZWxhdGUgY29sdW1ucyAoeW91IGRvbid0IG5lZWQgZXZlcnl0aGluZykNCg0KDQpgYGB7cn0NCmJhY2tncm91bmRfZW52IDwtIHN1YnNldChiYWNrZ3JvdW5kLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCkpDQpiYWNrZ3JvdW5kX2Vudl9jb3IgPC0gY29yKGJhY2tncm91bmRfZW52LCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihiYWNrZ3JvdW5kX2Vudl9jb3IsICIuLi9vdXRwdXQvZW52L2JhY2tncm91bmRfZW52X2NvcnIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCmJhY2tncm91bmRfY29ycnBsb3QgPC0gY29ycnBsb3QoYmFja2dyb3VuZF9lbnZfY29yICwgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsIG9yZGVyID0gImFscGhhYmV0IiwgdGwuY2V4ID0gMC44KSANCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvYmFja2dyb3VuZF9lbnZjb3JyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCnRvIGdldCBzb21lIGRlbnNpdHkgcGxvdHMgYWxsIGluIG9uZSBncmFwaGljLCB5b3UgbmVlZCB0byBjaGFuZ2UgY2h1bmsgb3V0cHV0IHRvIGluIGNvbnNvbGUsIHRoZW4gZ28gdG8gdGhlIHBsb3QgdGFiLCBtYWtlIGl0IGZpbGwgdGhlIHNjcmVlbiwgdGhlbiBydW4gdGhlbiBtYWtlIGJpZ2dlciB0aGVuIHNhdmUgOiggKHByb2JhYmx5IGEgYmV0dGVyIHdheSAtIHRoaXMgc2VlbXMgdG8gYmUgYW4gaXNzdWUgd2l0aCBSU3R1ZGlvKQ0KYGBge3J9DQpwYXIobWZyb3c9Yyg0LDQpKQ0KZm9yKGkgaW4gMToxNil7DQogIHBsb3QoZGVuc2l0eShiYWNrZ3JvdW5kX2VudlssaV0sIG5hLnJtPVQpLCBtYWluID0gbmFtZXMoYmFja2dyb3VuZF9lbnYpW2ldKQ0KfQ0KYGBgDQpQVVQgVEhFIENIVU5LIE9VVFBVVCBCQUNLIFRPIElOTElORQ0KDQoNCmFkZCBuYWZvIHJlZ2lvbiBhbmQgZ2VhciB0eXBlIGludG8gdGhlIG1peCBDQU5UISENCg0KDQpmaXJzdCBzdWJzZXQgdGhlIGVudi5jb3JyZWxhdGUgY29sdW1ucyArIGJvdHRvbV9kZXB0aCAoeW91IGRvbid0IG5lZWQgZXZlcnl0aGluZykNCg0KYGBge3J9DQpiYWNrZ3JvdW5kX2VudmJvdGRlcHRoIDwtIHN1YnNldChiYWNrZ3JvdW5kLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCmJhY2tncm91bmRfZW52Ym90ZGVwdGhfY29yIDwtIGNvcihiYWNrZ3JvdW5kX2VudmJvdGRlcHRoLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihiYWNrZ3JvdW5kX2VudmJvdGRlcHRoX2NvciwgIi4uL291dHB1dC9lbnYvYmFja2dyb3VuZF9lbnZib3RkZXB0aF9jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCmJhY2tncm91bmRfY29ycnBsb3QgPC0gY29ycnBsb3QoYmFja2dyb3VuZF9lbnZib3RkZXB0aF9jb3IgLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgb3JkZXIgPSAiYWxwaGFiZXQiLCB0bC5jZXggPSAwLjgpIA0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9iYWNrZ3JvdW5kX2VudmJvdGRlcHRoX2Nvci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQoNCiMjIGNvcnJlbGF0aW9ucyBiZXR3ZWVuIHByZXNlbmNlIHBvaW50cw0KDQpjaGVjayB0byBzZWUgaWYgdGhlcmUgYXJlIGFueSBjb3JyZWxhdGlvbnMgaW4gdGhlIGVudi4gdmFyaWFibGVzDQoNCmZpcnN0IHN1YnNldCB0aGUgZW52LmNvcnJlbGF0ZSBjb2x1bW5zICh5b3UgZG9uJ3QgbmVlZCBldmVyeXRoaW5nKSB0aGVuIHVzZSBjb3IgdG8gZ2V0IHRoZSBjb3JyZWxhdGlvbiB2YWx1ZXMsIGFuZCB0aGVuIGNvcnJwbG90IGZvciBhIHZpc3VhbA0KDQpgYGB7cn0NCnByZXNfZW52IDwtIHN1YnNldChwcmVzZW5jZSwgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQpwcmVzX2Vudl9jb3IgPC0gY29yKHByZXNfZW52LCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihwcmVzX2Vudl9jb3IsICIuLi9vdXRwdXQvZW52L3ByZXNfZW52X2NvcnIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnByZXNfY29ycnBsb3QgPC0gY29ycnBsb3QocHJlc19lbnZfY29yICwgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsIG9yZGVyID0gImFscGhhYmV0IiwgdGwuY2V4ID0gMC44KSANCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvcHJlc19lbnZjb3JyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCnRvIGdldCBzb21lIGRlbnNpdHkgcGxvdHMgYWxsIGluIG9uZSBncmFwaGljLCB5b3UgbmVlZCB0byBjaGFuZ2UgY2h1bmsgb3V0cHV0IHRvIGluIGNvbnNvbGUsIHRoZW4gZ28gdG8gdGhlIHBsb3QgdGFiLCBtYWtlIGl0IGZpbGwgdGhlIHNjcmVlbiwgdGhlbiBydW4gdGhlbiBtYWtlIGJpZ2dlciB0aGVuIHNhdmUgOiggKHByb2JhYmx5IGEgYmV0dGVyIHdheSAtIHRoaXMgc2VlbXMgdG8gYmUgYW4gaXNzdWUgd2l0aCBSU3R1ZGlvKQ0KYGBge3J9DQpwYXIobWZyb3c9Yyg0LDQpKQ0KZm9yKGkgaW4gMToxNil7DQogIHBsb3QoZGVuc2l0eShwcmVzX2VudlssaV0sIG5hLnJtPVQpLCBtYWluID0gbmFtZXMocHJlc19lbnYpW2ldKQ0KfQ0KYGBgDQpQVVQgVEhFIENIVU5LIE9VVFBVVCBCQUNLIFRPIElOTElORQ0KDQoNCiMjIGRlbnNpdHkgcGxvdCB3aXRoIGJhY2tncm91bmQgYW5kIHByZXNlbmNlIGVudi4gZGF0YQ0KDQpJbnNwaXJlZCBieSBNZXJyb3cgMjAxMyAtIHRvcCBwYXJhZ3JhcGggb2YgcGFnZSAxMDYzIChhcmUgdGhlIHNwZWNpZXMgb2JzZXJ2YXRpb25zIHVuaWZvcm1seSBkaXN0cmlidXRlZCBvdmVyIHRoZSBiYWNrZ3JvdW5kLCBvciBhcmUgdGhleSBza2V3ZWQpDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IHRlbXBfZGVwdGgpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvdGVtcF9kZXB0aF9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IHRlbXBfc3VyZmFjZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wX3N1cmZhY2VfYmFja3ZzcHJlcy5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChwcmVzX2VudiwgYWVzKHggPSBjaGxfc3VyZmFjZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxfc3VyZmFjZV9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IGNobF9kZXB0aCkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9jaGxfZGVwdGhfYmFja3ZzcHJlcy5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChwcmVzX2VudiwgYWVzKHggPSBzYWxpbml0eV9zdXJmYWNlKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFLCBjb2xvdXIgPSAicmVkIikgKyBnZW9tX2RlbnNpdHkoZGF0YT1iYWNrZ3JvdW5kX2VudiwgbmEucm0gPSBUUlVFLCBjb2xvdXIgPSAiYmx1ZSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL3NhbGluaXR5X3N1cmZhY2VfYmFja3ZzcHJlcy5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChwcmVzX2VudiwgYWVzKHggPSBzYWxpbml0eV9kZXB0aCkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSwgY29sb3VyID0gInJlZCIpICsgZ2VvbV9kZW5zaXR5KGRhdGE9YmFja2dyb3VuZF9lbnYsIG5hLnJtID0gVFJVRSwgY29sb3VyID0gImJsdWUiKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy9zYWxpbml0eV9kZXB0aF9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IG8yX3N1cmZhY2UpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbzJfc3VyZmFjZV9iYWNrdnNwcmVzLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KHByZXNfZW52LCBhZXMoeCA9IG8yX2RlcHRoKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFLCBjb2xvdXIgPSAicmVkIikgKyBnZW9tX2RlbnNpdHkoZGF0YT1iYWNrZ3JvdW5kX2VudiwgbmEucm0gPSBUUlVFLCBjb2xvdXIgPSAiYmx1ZSIpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvc2ltcGxlX3Bsb3RzL28yX2RlcHRoX2JhY2t2c3ByZXMucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QocHJlc19lbnYsIGFlcyh4ID0gbWxwX3N1cmZhY2UpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvbWxwX2JhY2t2c3ByZXMucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QocHJlc19lbnYsIGFlcyh4ID0gc3NoX3N1cmZhY2UpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJyZWQiKSArIGdlb21fZGVuc2l0eShkYXRhPWJhY2tncm91bmRfZW52LCBuYS5ybSA9IFRSVUUsIGNvbG91ciA9ICJibHVlIikNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9zaW1wbGVfcGxvdHMvc3NoX2JhY2t2c3ByZXMucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KDQojIE5BRk8gUmVnaW9ucw0KDQpjb21wYXJlIHRoZSBlbnZpcm9ubWVudGFsIGNvcnJlbGF0ZXMgYmV0d2VlbiBkaWZmZXJlbnQgTkFGTyByZWdpb25zDQoNCmZpcnN0IHNlZSB3aGljaCBuYWZvIHpvbmVzIHdlcmUgc2FtcGxlZCBpbiBlYWNoIHllYXINCmBgYHtyIHByZXNlbmNlIG5hZm8gYnkgeWVhcn0NCnByZXNlbmNlJG5hZm9fem9uZSA8LSBhcy5jaGFyYWN0ZXIocHJlc2VuY2UkbmFmb196b25lKQ0KbmFmb19ieV95ciA8LSB3aXRoKHByZXNlbmNlLCB0YWJsZSh5ZWFyLCBuYWZvX3pvbmUpKQ0Kd3JpdGUuY3N2KG5hZm9fYnlfeXIsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9uYWZvem9uZV9ieV95ci5jc3YiKQ0KbmFmb19ieV95cg0KYGBgDQoNCmFuZCBieSBtb250aA0KYGBge3IgcHJzZW5jZSBuYWZvIGJ5IG1vbnRofQ0KbmFmb19ieV9tdGggPC0gd2l0aChwcmVzZW5jZSwgdGFibGUobmFmb196b25lLCBtb250aCkpDQp3cml0ZS5jc3YobmFmb19ieV9tdGgsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9uYWZvem9uZV9ieV9tdGguY3N2IikNCm5hZm9fYnlfbXRoDQpgYGANCg0KSW50ZXJlc3RpbmcgdGhhdCB0aGVyZSBpcyBhIHBvaW50IGluIDFDIC0gdGhpcyBpcyBvdXRzaWRlIENhbmFkaWFuIHdhdGVycyByZW1vdmUgZnJvbSB0aGUgZGF0YXNldA0KYGBge3J9DQpwcmVzYWIgPC0gcHJlc2FiWyEocHJlc2FiJG5hZm9fem9uZSA9PSAiMUMiICYgcHJlc2FiJG9jY3VycmVuY2UgPT0gIjEiKSwgXQ0Kd3JpdGUuY3N2KHByZXNhYiwgIi4uL291dHB1dC9iaW8vcHJlc2FiXzEway5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCnByZXNlbmNlIDwtIHByZXNlbmNlWyEocHJlc2VuY2UkbmFmb196b25lID09ICIxQyIpLCBdDQpgYGANCg0KYW5kIGJ5IG1vbnRoIGFnYWluDQpgYGB7ciBwcnNlbmNlIG5hZm8gYnkgbW9udGgyfQ0KbmFmb19ieV9tdGggPC0gd2l0aChwcmVzZW5jZSwgdGFibGUobmFmb196b25lLCBtb250aCkpDQp3cml0ZS5jc3YobmFmb19ieV9tdGgsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9uYWZvem9uZV9ieV9tdGguY3N2IikNCm5hZm9fYnlfbXRoDQpgYGANCg0KDQojIyBkZW5zaXR5IHBsb3Qgd2l0aCBiYWNrZ3JvdW5kIGFuZCBwcmVzZW5jZSBlbnYuIGRhdGEgYnkgTkFGTyByZWdpb24NCg0KV2hhdCBJIHdhbnQgdG8gc2VlIGlmIGlmIHRoZXJlIGlzIGEgbWFya2VkIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgZW52LiBjb3JyZWxhdGVzIG9mIHRoZSBwcmVzZW5jZSBwb2ludHMgYmV0d2VlbiBOQUZPIHJlZ2lvbnMuIFRoaXMgaXMgYWxzbyB0byB0cnkgZGVhbCB3aXRoIHNhbXBsaW5nIGJpYXMgKGIvYyB0aGUgd2hvbGUgcmVnaW9uIGlzIG5vdCB1bmlmb3JtbHkgc2FtcGxlZCBpbiBlYWNoIG1vbnRoLCBidXQgcmF0aGVyIG5hZm8gcmVnaW9ucyBoYXZlIGEgc3Ryb25nIG1vbnRoIGJpYXMpDQoNCmZpcnN0IGNyZWF0ZSBOQUZPLXJlZ2lvbiBkYXRhc2V0cw0KDQpgYGB7ciBwcmVzZW5jZSBieSBuYWZvfQ0KbmFmbzBhIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIwQSIpDQpuYWZvMGIgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjBCIikNCm5hZm8yZyA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiMkciKQ0KbmFmbzJoIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIySCIpDQpuYWZvMmogPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjJKIikNCm5hZm8zayA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiM0siKQ0KbmFmbzNsIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIzTCIpDQpuYWZvM20gPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjNNIikNCm5hZm8zbiA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiM04iKQ0KbmFmbzNvIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIzTyIpDQpuYWZvM3BzIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICIzUHMiKQ0KbmFmbzRyIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICI0UiIpDQpuYWZvNHMgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjRTIikNCm5hZm80dCA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiNFQiKQ0KbmFmbzR2biA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiNFZuIikNCm5hZm80dnMgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjRWcyIpDQpuYWZvNHcgPC0gc3Vic2V0KHByZXNlbmNlLCBuYWZvX3pvbmUgPT0gIjRXIikNCm5hZm80eCA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiNFgiKQ0KbmFmbzV5IDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICI1WSIpDQpuYWZvNXplIDwtIHN1YnNldChwcmVzZW5jZSwgbmFmb196b25lID09ICI1WkUiKQ0KbmFmb2h1ZHNvbiA8LSBzdWJzZXQocHJlc2VuY2UsIG5hZm9fem9uZSA9PSAiSHVkc29uU3RyYWl0IikNCmBgYA0KDQpwbG90IGJ5IGVhY2ggdmFyaWFibGUsIGxlc3MgM20gKDIgc2FtcGxlcykgYW5kIDV6ZSAoMiBzYW1wbGVzKQ0KYGBge3IgcHJlc2VuY2UgYnkgbmFmbyBieSB2YXJpYWJsZX0NCmdncGxvdChuYWZvMGEsIGFlcyh4ID0gdGVtcF9zdXJmYWNlLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL3RlbXBfc3VyZmFjZV9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IHRlbXBfZGVwdGgsIGNvbG91ciA9IG5hZm9fem9uZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMGIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmosIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2ssIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2wsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM28sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM3BzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRyLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dnMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNXksIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvaHVkc29uLCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X25hZm9fcGxvdHMvdGVtcF9kZXB0aF9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IGNobF9zdXJmYWNlLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL2NobF9zdXJmYWNlX25hZm8ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChuYWZvMGEsIGFlcyh4ID0gY2hsX2RlcHRoLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL2NobF9kZXB0aF9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IHNhbGluaXR5X3N1cmZhY2UsIGNvbG91ciA9IG5hZm9fem9uZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMGIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmosIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2ssIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2wsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM28sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM3BzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRyLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dnMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNXksIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvaHVkc29uLCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X25hZm9fcGxvdHMvc2FsaW5pdHlfc3VyZmFjZV9uYWZvLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QobmFmbzBhLCBhZXMoeCA9IHNhbGluaXR5X2RlcHRoLCBjb2xvdXIgPSBuYWZvX3pvbmUpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzBiLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJnLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJoLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzJqLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNrLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNsLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNvLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzNwcywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80ciwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dm4sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR3LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR4LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzV5LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmb2h1ZHNvbiwgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9uYWZvX3Bsb3RzL3NhbGluaXR5X2RlcHRoX25hZm8ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChuYWZvMGEsIGFlcyh4ID0gbzJfc3VyZmFjZSwgY29sb3VyID0gbmFmb196b25lKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8wYiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yZywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zaywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zcHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80eCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm81eSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm9odWRzb24sIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfbmFmb19wbG90cy9vMl9zdXJmYWNlX25hZm8ucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChuYWZvMGEsIGFlcyh4ID0gbzJfZGVwdGgsIGNvbG91ciA9IG5hZm9fem9uZSkpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMGIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvMmosIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2ssIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM2wsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM28sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvM3BzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRyLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzRzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dnMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHcsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHgsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNXksIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvaHVkc29uLCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X25hZm9fcGxvdHMvbzJfZGVwdGhfbmFmby5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KG5hZm8wYSwgYWVzKHggPSBtbHBfc3VyZmFjZSwgY29sb3VyID0gbmFmb196b25lKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8wYiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yZywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zaywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zcHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80eCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm81eSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm9odWRzb24sIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfbmFmb19wbG90cy9tbHBfbmFmby5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KG5hZm8wYSwgYWVzKHggPSBzc2hfc3VyZmFjZSwgY29sb3VyID0gbmFmb196b25lKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8wYiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yZywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8yaiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zaywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbiwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zbywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm8zcHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHIsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1uYWZvNHZuLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9bmFmbzR2cywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80dywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm80eCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm81eSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPW5hZm9odWRzb24sIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfbmFmb19wbG90cy9zc2hfbmFmby5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQoNCg0KTGV0J3MgcGxvdCB0aGUgdmFyaWFibGVzIGJ5IG5hZm8gcmVnaW9uL3llYXIgdGhlbiBieSBtb250aA0KDQoNCmBgYHtyfQ0KcHI5OCA8LSBzdWJzZXQocHJlc2VuY2UsIHllYXIgPT0gIjE5OTgiKQ0KYm94cGxvdChwcjk4JHRlbXBfZGVwdGggfiBwcjk4JG5hZm9fem9uZSwgeGxhYiA9ICJOQUZPIFJlZ2lvbiIsIHlsYWIgPSAiVGVtcGVyYXR1cmUgKEtlbHZpbikiLCBtYWluID0gIlRlbXBlcmF0dXJlIGF0IE9ic2VydmF0aW9uIERlcHRoIHBlciBOQUZPIFpvbmUiKQ0KYGBgDQoNCmBgYHtyfQ0KcHI5OCA8LSBzdWJzZXQocHJlc2VuY2UsIHllYXIgPT0gIjE5OTgiKQ0KcHIxMSA8LSBzdWJzZXQocHJlc2VuY2UsIHllYXIgPT0gIjIwMTEiKQ0KcGFyKG1mcm93PWMoMiwxKSkNCmJveHBsb3QocHI5OCR0ZW1wX2RlcHRoIH4gcHI5OCRuYWZvX3pvbmUsIHhsYWIgPSAiTkFGTyBSZWdpb24iLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiBEZXB0aCBwZXIgTkFGTyBab25lIikNCmJveHBsb3QocHIxMSR0ZW1wX2RlcHRoIH4gcHIxMSRuYWZvX3pvbmUsIHhsYWIgPSAiTkFGTyBSZWdpb24iLCB5bGFiID0gIlRlbXBlcmF0dXJlIChLZWx2aW4pIiwgbWFpbiA9ICJUZW1wZXJhdHVyZSBhdCBPYnNlcnZhdGlvbiBEZXB0aCBwZXIgTkFGTyBab25lIikNCmBgYA0KDQpvayBzY3JhcCB0aGUgbmFmbyByZWdpb24gYW5hbHlzaXMgLSBpdCBpcyB0b28gbWl4ZWQgdXAgd2l0aCBtb250aCAoc28gc2VlaW5nIGlmIHJlZ2lvbiBvciBtb250aCBpcyBhIGZhY3RvciB0aGF0IG5lZWRzIHRvIGJlIGZhY3RvcmVkIGluIHRvIHRoZSBtb2RlbCBpcyBub3QgYXBwcm9wcmlhdGUpDQoNCiMgcmVtYXAgd2hvIHNhbXBsZWQNCg0KTm93IGxldHMgY2hlY2sgdGhlIG51bWJlciBvZiByZWNvcmRzIGFuZCBzcGF0aWFsLXRlbXBvcmFsIGRpc3RyaWJ1dGlvbiBvZiB0aGUgb2JzZXJ2YXRpb25zIGJ5IGluc3RpdHV0aW9uIGNvZGUgdG8gbWFrZSBzdXJlIG5vbmUgYXJlIGRvZGd5DQoNCmZpcnN0IGEgdGFibGUgb2YgaG93IG1hbnkgb2JzZXJ2YXRpb25zIGVhY2ggaW5zdGl0dWlvbmNvZGUgaGFzDQpgYGB7ciBpbnN0aXR1dGlvbiBjb2RlIGFuYWx5c2lzIC0gY291bnR9DQpvYnNfYnlfaW5zIDwtIGNvdW50KHByZXNlbmNlLCAiaW5zdGl0dXRpb25jb2RlIikNCm9ic19ieV9pbnMNCndyaXRlLmNzdihvYnNfYnlfaW5zLCBmaWxlID0gIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvbm9fb2JzZXJ2YXRpb25zX2luc3RpdHV0aW9uY29kZS5jc3YiKQ0KYGBgDQpvayBzbyBORUZTQyBhbmQgUk9NIG9ubHkgaGF2ZSBvbmUgcG9pbnQgZWFjaA0KDQpMZXRzIHRha2UgYSBsb29rIGF0IHRoZSBzcGF0aWFsIGJyZWFrZG93biBvZiB0aGVzZSBpbnN0aXR1dGlvbnMuRmlyc3QgYWxsIHBvaW50cy4uLg0KDQpgYGB7cn0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM4LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiQWxsIE9jY3VycmVuY2VzIiwgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMocHJlc2VuY2UkZGVjaW1hbExvbmdpdHVkZSwgcHJlc2VuY2UkZGVjaW1hbExhdGl0dWRlLCBjb2wgPSAicmVkIikgI3RoaXMgYWRkcyBwb2ludHMgdG8gdGhlIG1hcGV0IiwgeGxhYiA9ICJMb25naXR1ZGUiLCB5bGFiID0gIkxhdGl0dWRlIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvYWxsX29jY3VycmVuY2VzLnBuZyIpICN0aGlzIHByaW50cyBhIHBuZyBvZiB0aGUgcGxvdA0KZGV2Lm9mZigpICN0aGlzIHR1cm5zIG9mZiB0aGUgcHJpbnQgY29tbWFuZA0KYGBgDQpOb3RlIHRoZXJlIGlzIG9uZSBwb2ludCB1cCBieSBpY2VsYW5kIHRoYXQgeW91IHNob3VsZCBnZXQgcmlkIG9mIChJY2VsYW5kaWMgcG9wdWxhdGlvbiB0aG91Z2h0IHRvIGJlIHNlcGVyYXRlIGZyb20gTGFicmFkb3IsIGJ1dCBpdCBpcyB1bmNsZWFyIGlmIHRoaXMgaXMgdHJ1ZSBvciBub3QpLg0KDQpNYXAgdGhlIGluc3RpdHV0aW9uY29kZSA9PSBBUkMgb25seSBkYXRhLi4uDQpgYGB7ciBtYXAgb2JzIGJ5IGluc3RpdHV0dWlvbn0NCkFSQ19vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJBUkMiLCBdDQptYXAyIDwtIGdldE1hcChyZXNvbHV0aW9uID0gImxvdyIpICNjcmVhdGVzIGFuIG9iamVjdCBjYWxsZWQgbWFwIGF0IGxvdyByZXNvdWx0aW9uDQpwbG90KG1hcDIsIHhsaW0gPSBjKC03MCwgLTQzKSwgeWxpbSA9YygzOSwgNzApLCBhc3AgPSAxLCBtYWluID0gIkFyYyBPY2N1cnJlbmNlcyIsIGNvbCA9ICJjb3Juc2lsayIpICN0aGUgeCBhbmQgeSBsaW0gYXJlIHRoZSBsb25nLWxhdCBib3VuZHMgb2YgdGhlIG1hcA0KcG9pbnRzKEFSQ19vYnMkZGVjaW1hbExvbmdpdHVkZSwgQVJDX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9BUkNfb2NjdXJyZW5jZXNfYWxsLnBuZyIpICN0aGlzIHByaW50cyBhIHBuZyBvZiB0aGUgcGxvdA0KZGV2Lm9mZigpICN0aGlzIHR1cm5zIG9mZiB0aGUgcHJpbnQgY29tbWFuZA0KDQpERk9DRU5BUkNfb2JzIDwtIHByZXNlbmNlW3ByZXNlbmNlJGluc3RpdHV0aW9uY29kZSA9PSAiREZPQ0VOQVJDIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJERk8gQ2VudHJhbCAmIEFyY3RpYyBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhERk9DRU5BUkNfb2JzJGRlY2ltYWxMb25naXR1ZGUsIERGT0NFTkFSQ19vYnMkZGVjaW1hbExhdGl0dWRlLCBjb2wgPSAicmVkIikgI3RoaXMgYWRkcyBwb2ludHMgdG8gdGhlIG1hcGV0IiwgeGxhYiA9ICJMb25naXR1ZGUiLCB5bGFiID0gIkxhdGl0dWRlIikNCmRldi5jb3B5KHBuZywgIi4uL291dHB1dC9iaW8vc2FtcGxpbmdpbnN0aXR1dGlvbnMvREZPQ0VOQVJDX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KREZPR3VsZl9vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJERk9HdWxmIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJERk8gR3VsZiBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhERk9HdWxmX29icyRkZWNpbWFsTG9uZ2l0dWRlLCBERk9HdWxmX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9ERk9HdWxmX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KREZPSVNETV9vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJERk9JU0RNIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJERk8gSVNETSBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhERk9JU0RNX29icyRkZWNpbWFsTG9uZ2l0dWRlLCBERk9JU0RNX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9ERk9JU0RNX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KREZPTVRNU19vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJERk9NVE1TIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJERk8gTWFyaXRpbWVzIE9jY3VycmVuY2VzIiwgIGNvbCA9ICJjb3Juc2lsayIpICN0aGUgeCBhbmQgeSBsaW0gYXJlIHRoZSBsb25nLWxhdCBib3VuZHMgb2YgdGhlIG1hcA0KcG9pbnRzKERGT01UTVNfb2JzJGRlY2ltYWxMb25naXR1ZGUsIERGT01UTVNfb2JzJGRlY2ltYWxMYXRpdHVkZSwgY29sID0gInJlZCIpICN0aGlzIGFkZHMgcG9pbnRzIHRvIHRoZSBtYXBldCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL0RGT01UTVNfb2NjdXJyZW5jZXNfYWxsLnBuZyIpICN0aGlzIHByaW50cyBhIHBuZyBvZiB0aGUgcGxvdA0KZGV2Lm9mZigpICN0aGlzIHR1cm5zIG9mZiB0aGUgcHJpbnQgY29tbWFuZA0KDQpERk9OTF9vYnMgPC0gcHJlc2VuY2VbcHJlc2VuY2UkaW5zdGl0dXRpb25jb2RlID09ICJERk9OTCIsIF0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM5LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiREZPIE5ld2ZvdXVuZGxhbmQgJiBMYWJyYWRvciBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhERk9OTF9vYnMkZGVjaW1hbExvbmdpdHVkZSwgREZPTkxfb2JzJGRlY2ltYWxMYXRpdHVkZSwgY29sID0gInJlZCIpICN0aGlzIGFkZHMgcG9pbnRzIHRvIHRoZSBtYXBldCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL0RGT05MX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KREZPUUNfb2JzIDwtIHByZXNlbmNlW3ByZXNlbmNlJGluc3RpdHV0aW9uY29kZSA9PSAiREZPUUMiLCBdDQptYXAyIDwtIGdldE1hcChyZXNvbHV0aW9uID0gImxvdyIpICNjcmVhdGVzIGFuIG9iamVjdCBjYWxsZWQgbWFwIGF0IGxvdyByZXNvdWx0aW9uDQpwbG90KG1hcDIsIHhsaW0gPSBjKC03MCwgLTQzKSwgeWxpbSA9YygzOSwgNzApLCBhc3AgPSAxLCBtYWluID0gIkRGTyBRdWViZWMgT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoREZPUUNfb2JzJGRlY2ltYWxMb25naXR1ZGUsIERGT1FDX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9ERk9RQ19vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpkZXYub2ZmKCkgI3RoaXMgdHVybnMgb2ZmIHRoZSBwcmludCBjb21tYW5kDQoNCk1haW5lRE1SX29icyA8LSBwcmVzZW5jZVtwcmVzZW5jZSRpbnN0aXR1dGlvbmNvZGUgPT0gIk1haW5lRE1SIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJNYWluZSBETVIgT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoTWFpbmVETVJfb2JzJGRlY2ltYWxMb25naXR1ZGUsIE1haW5lRE1SX29icyRkZWNpbWFsTGF0aXR1ZGUsIGNvbCA9ICJyZWQiKSAjdGhpcyBhZGRzIHBvaW50cyB0byB0aGUgbWFwZXQiLCB4bGFiID0gIkxvbmdpdHVkZSIsIHlsYWIgPSAiTGF0aXR1ZGUiKQ0KZGV2LmNvcHkocG5nLCAiLi4vb3V0cHV0L2Jpby9zYW1wbGluZ2luc3RpdHV0aW9ucy9NYWluZURNUl9vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpkZXYub2ZmKCkgI3RoaXMgdHVybnMgb2ZmIHRoZSBwcmludCBjb21tYW5kDQoNCk5FRlNDX29icyA8LSBwcmVzZW5jZVtwcmVzZW5jZSRpbnN0aXR1dGlvbmNvZGUgPT0gIk5FRlNDIiwgXQ0KbWFwMiA8LSBnZXRNYXAocmVzb2x1dGlvbiA9ICJsb3ciKSAjY3JlYXRlcyBhbiBvYmplY3QgY2FsbGVkIG1hcCBhdCBsb3cgcmVzb3VsdGlvbg0KcGxvdChtYXAyLCB4bGltID0gYygtNzAsIC00MyksIHlsaW0gPWMoMzksIDcwKSwgYXNwID0gMSwgbWFpbiA9ICJORUZTQyBPY2N1cnJlbmNlcyIsICBjb2wgPSAiY29ybnNpbGsiKSAjdGhlIHggYW5kIHkgbGltIGFyZSB0aGUgbG9uZy1sYXQgYm91bmRzIG9mIHRoZSBtYXANCnBvaW50cyhORUZTQ19vYnMkZGVjaW1hbExvbmdpdHVkZSwgTkVGU0Nfb2JzJGRlY2ltYWxMYXRpdHVkZSwgY29sID0gInJlZCIpICN0aGlzIGFkZHMgcG9pbnRzIHRvIHRoZSBtYXBldCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL05FRlNDX29jY3VycmVuY2VzX2FsbC5wbmciKSAjdGhpcyBwcmludHMgYSBwbmcgb2YgdGhlIHBsb3QNCmRldi5vZmYoKSAjdGhpcyB0dXJucyBvZmYgdGhlIHByaW50IGNvbW1hbmQNCg0KUk9NX29icyA8LSBwcmVzZW5jZVtwcmVzZW5jZSRpbnN0aXR1dGlvbmNvZGUgPT0gIlJPTSIsIF0NCm1hcDIgPC0gZ2V0TWFwKHJlc29sdXRpb24gPSAibG93IikgI2NyZWF0ZXMgYW4gb2JqZWN0IGNhbGxlZCBtYXAgYXQgbG93IHJlc291bHRpb24NCnBsb3QobWFwMiwgeGxpbSA9IGMoLTcwLCAtNDMpLCB5bGltID1jKDM5LCA3MCksIGFzcCA9IDEsIG1haW4gPSAiUm95YWwgT250YXJpbyBNdXNldW0gT2NjdXJyZW5jZXMiLCAgY29sID0gImNvcm5zaWxrIikgI3RoZSB4IGFuZCB5IGxpbSBhcmUgdGhlIGxvbmctbGF0IGJvdW5kcyBvZiB0aGUgbWFwDQpwb2ludHMoUk9NX29icyRkZWNpbWFsTG9uZ2l0dWRlLCBST01fb2JzJGRlY2ltYWxMYXRpdHVkZSwgY29sID0gInJlZCIpICN0aGlzIGFkZHMgcG9pbnRzIHRvIHRoZSBtYXBldCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvYmlvL3NhbXBsaW5naW5zdGl0dXRpb25zL1JPTV9vY2N1cnJlbmNlc19hbGwucG5nIikgI3RoaXMgcHJpbnRzIGEgcG5nIG9mIHRoZSBwbG90DQpgYGANCg0KIyBjaGVjayBmb3IgZ2VhciB0eXBlDQoNCndoYXQgYXJlIHRoZSB1bmlxdWUgZ2VhciB0eXBlcyB5b3UgaGF2ZSBpbiB5b3VyIHByZXNlbmNlIGRhdGEsIGFuZCBob3cgbWFueT8NCg0KYGBge3Igb2JzZXJ2YXRpb24gYnkgY2VsbCAtIHRvdGFsfQ0KZ2Vhcl9jb3VudCA8LSBjb3VudChwcmVzZW5jZSwgImdlYXIiKQ0Kd3JpdGUuY3N2KGdlYXJfY291bnQsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9nZWFyX2NvdW50LmNzdiIpDQpnZWFyX2NvdW50DQpgYGANCg0Kc28gdGhlIHZhc3QgbWFqb3JpdHkgYXJlIHRyYXdscyBvZiBzb21lIHR5cGUuIA0KDQptYXAgdGhlIGdlYXIgdXNhZ2UgaW4gQXJjZ2lzIChnZWFyX3R5cGVfbWFwKQ0KDQpjcmVhdGUgYSB0YWJsZSBvZiBnZWFyIHVzZSBieSBtb250aA0KDQpgYGB7cn0NCmdlYXJieV9tdGggPC0gd2l0aChwcmVzZW5jZSwgdGFibGUoZ2VhciwgbW9udGgpKQ0Kd3JpdGUuY3N2KGdlYXJieV9tdGgsIGZpbGUgPSAiLi4vb3V0cHV0L2Jpby9nZWFyX2J5X210aC5jc3YiKQ0KZ2VhcmJ5X210aA0KYGBgDQoNCldoYXQgSSB3YW50IHRvIHNlZSBpZiBpZiB0aGVyZSBpcyBhIG1hcmtlZCBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGVudi4gY29ycmVsYXRlcyBvZiB0aGUgcHJlc2VuY2UgcG9pbnRzIGJldHdlZW4gZ2VhciB0eXBlIHVzZWQuIFRoaXMgaXMgYWxzbyB0byB0cnkgZGVhbCB3aXRoIGRldGVjdGlvbiBiaWFzIGJldHdlZW4gZ2VhciB0eXBlIChiL2MgdGhlIHdob2xlIHJlZ2lvbiBpcyBub3QgdW5pZm9ybWx5IHNhbXBsZWQgYnkgdGhlIHNhbWUgZ2VhciB0eXBlKQ0KDQpmaXJzdCBjcmVhdGUgZ2VhciBkYXRhc2V0cw0KDQpgYGB7ciBwcmVzZW5jZSBieSBnZWFyfQ0KcHJlc2VuY2UkZ2VhciA8LSBhcy5jaGFyYWN0ZXIocHJlc2VuY2UkZ2VhcikNCmJvdHRvbV90cmF3bCA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bCIpDQpib3R0b21fdHJhd2xfYWxmcmVkb18wMyA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bF9hbGZyZWRvXzAzIikNCmJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCIpDQpib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwIikNCmJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gImJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSIpDQpib3R0b21fdHJhd2xfY29zbW9zXzI2MDAgPC0gc3Vic2V0KHByZXNlbmNlLCBnZWFyID09ICJib3R0b21fdHJhd2xfY29zbW9zXzI2MDAiKQ0KYm90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBIDwtIHN1YnNldChwcmVzZW5jZSwgZ2VhciA9PSAiYm90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBIikNCnVua25vd24gPC0gc3Vic2V0KHByZXNlbmNlLCBnZWFyID09ICJ1bmtub3duIikNCnZlcnRpY2FsX3BsYW5rdG9uX3RvdyA8LSBzdWJzZXQocHJlc2VuY2UsIGdlYXIgPT0gInZlcnRpY2FsX3BsYW5rdG9uX3RvdyIpDQpgYGANCg0KcGxvdCBieSBlYWNoIHZhcmlhYmxlLCBsZXNzIDNtICgyIHNhbXBsZXMpIDFjIChvbmUgc2FtcGxlKSBhbmQgNXplICh6ZXJvIHNhbXBsZXM/ISkNCmBgYHtyIHByZXNlbmNlIGJ5IGdlYXIgYnkgdmFyaWFibGV9DQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IHRlbXBfc3VyZmFjZSwgY29sb3VyID0gZ2VhcikpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfYWxmcmVkb18wMywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzIxLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2Nvc21vc18yNjAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dW5rbm93biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXZlcnRpY2FsX3BsYW5rdG9uX3RvdywgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9nZWFyX3Bsb3RzL3RlbXBfc3VyZmFjZV9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IHRlbXBfZGVwdGgsIGNvbG91ciA9IGdlYXIpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2FsZnJlZG9fMDMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jb3Ntb3NfMjYwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF93ZXN0ZXJuX0lJQSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXVua25vd24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT12ZXJ0aWNhbF9wbGFua3Rvbl90b3csIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfZ2Vhcl9wbG90cy90ZW1wX2RlcHRoX2dlYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQoNCmdncGxvdChib3R0b21fdHJhd2wsIGFlcyh4ID0gY2hsX3N1cmZhY2UsIGNvbG91ciA9IGdlYXIpKSArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2FsZnJlZG9fMDMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jb3Ntb3NfMjYwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF93ZXN0ZXJuX0lJQSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXVua25vd24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT12ZXJ0aWNhbF9wbGFua3Rvbl90b3csIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfZ2Vhcl9wbG90cy9jaGxfc3VyZmFjZV9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IGNobF9kZXB0aCwgY29sb3VyID0gZ2VhcikpICArIGdlb21fZGVuc2l0eShuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2FsZnJlZG9fMDMsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTQsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMTgwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8yMSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jb3Ntb3NfMjYwMCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF93ZXN0ZXJuX0lJQSwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXVua25vd24sIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT12ZXJ0aWNhbF9wbGFua3Rvbl90b3csIG5hLnJtID0gVFJVRSkNCmRldi5jb3B5KHBuZywiLi4vb3V0cHV0L2Vudi9lbnZfYnlfZ2Vhcl9wbG90cy9jaGxfZGVwdGhfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSBzYWxpbml0eV9zdXJmYWNlLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvc2FsaW5pdHlfc3VyZmFjZV9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IHNhbGluaXR5X2RlcHRoLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvc2FsaW5pdHlfZGVwdGhfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSBvMl9zdXJmYWNlLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvbzJfc3VyZmFjZV9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IG8yX2RlcHRoLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvbzJfZGVwdGhfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCg0KZ2dwbG90KGJvdHRvbV90cmF3bCwgYWVzKHggPSBtbHBfc3VyZmFjZSwgY29sb3VyID0gZ2VhcikpICsgZ2VvbV9kZW5zaXR5KG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfYWxmcmVkb18wMywgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xNCwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9jYW1wZWxlbl8xODAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzIxLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2Nvc21vc18yNjAwLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX3dlc3Rlcm5fSUlBLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dW5rbm93biwgbmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPXZlcnRpY2FsX3BsYW5rdG9uX3RvdywgbmEucm0gPSBUUlVFKQ0KZGV2LmNvcHkocG5nLCIuLi9vdXRwdXQvZW52L2Vudl9ieV9nZWFyX3Bsb3RzL21scF9nZWFyLnBuZyIpICMgdG8gYXV0b21hdGljYWxseSBzYXZlIHRoZSBwbG90IHRvIGEgcG5nIEFORCBzaG93IGl0IGlubGluZQ0KZGV2Lm9mZigpICMgc3RvcHMgYXV0b21hdGljIHNhdmluZyBvZiB0aGUgcGxvdCB0byBhIHBuZw0KDQpnZ3Bsb3QoYm90dG9tX3RyYXdsLCBhZXMoeCA9IHNzaF9zdXJmYWNlLCBjb2xvdXIgPSBnZWFyKSkgKyBnZW9tX2RlbnNpdHkobmEucm0gPSBUUlVFKSArIGdlb21fZGVuc2l0eShkYXRhPWJvdHRvbV90cmF3bF9hbGZyZWRvXzAzLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE0LCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9Ym90dG9tX3RyYXdsX2NhbXBlbGVuXzE4MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY2FtcGVsZW5fMjEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfY29zbW9zXzI2MDAsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT1ib3R0b21fdHJhd2xfd2VzdGVybl9JSUEsIG5hLnJtID0gVFJVRSkgKyBnZW9tX2RlbnNpdHkoZGF0YT11bmtub3duLCBuYS5ybSA9IFRSVUUpICsgZ2VvbV9kZW5zaXR5KGRhdGE9dmVydGljYWxfcGxhbmt0b25fdG93LCBuYS5ybSA9IFRSVUUpDQpkZXYuY29weShwbmcsIi4uL291dHB1dC9lbnYvZW52X2J5X2dlYXJfcGxvdHMvc3NoX2dlYXIucG5nIikgIyB0byBhdXRvbWF0aWNhbGx5IHNhdmUgdGhlIHBsb3QgdG8gYSBwbmcgQU5EIHNob3cgaXQgaW5saW5lDQpkZXYub2ZmKCkgIyBzdG9wcyBhdXRvbWF0aWMgc2F2aW5nIG9mIHRoZSBwbG90IHRvIGEgcG5nDQpgYGANCg0KDQpgYGB7cn0NCnBhcihtYXI9Yyg3LDUsMSwxKSkNCmJveHBsb3QocHJlc2VuY2UkdGVtcF9kZXB0aCB+IHByZXNlbmNlJGdlYXIsIHlsYWIgPSAiVGVtcGVyYXR1cmUgKEtlbHZpbikiLCBtYWluID0gIlRlbXBlcmF0dXJlIGF0IE9ic2VydmF0aW9uIERlcHRoIGJ5IGdlYXIgdHlwZSIsIGxhcyA9IDIpDQpkZXYuY29weShwbmcsICIuLi9vdXRwdXQvZW52L3NpbXBsZV9wbG90cy90ZW1wZXJhdHVyZV9ib3hwbG90X2RlcHRfZ2Vhci5wbmciKSAjIHRvIGF1dG9tYXRpY2FsbHkgc2F2ZSB0aGUgcGxvdCB0byBhIHBuZyBBTkQgc2hvdyBpdCBpbmxpbmUNCmRldi5vZmYoKSAjIHN0b3BzIGF1dG9tYXRpYyBzYXZpbmcgb2YgdGhlIHBsb3QgdG8gYSBwbmcNCmBgYA0KDQp3aGF0IGFib3V0IGEga3J1c2thbCB3YWxsYWNlIHRlc3Q/DQoNCmBgYHtyfQ0Ka3J1c2thbC50ZXN0KHByZXNlbmNlJHRlbXBfZGVwdGggfiBwcmVzZW5jZSRnZWFyKQ0KYGBgDQpPayBzbyB0aGVyZSBpcyBhIHN0YXRpc3RpY2FsbHkgc2lnIGRpZmZlcmVuY2Ugc29tZXdoZXJlIGluIHRoZSB0ZW1wIGF0IGRlcHRoIHJlcG9ydGVkIGJ5IHRoZSBnZWFyIHR5cGUgKEtydXNrYWwtV2FsbGlzIGNoaS1zcXVhcmVkID0gMjQ4LjI3LCBkZiA9IDcsIHAtdmFsdWUgPCAyLjJlLTE2KQ0KDQpUbyBzZWUgd2hlcmUgdGhlIGRpZmZlcmVuY2UocykgYXJlIHJ1biBhIER1bm4gdGVzdCBaYXIgKDIwMTApIHN0YXRlcyB0aGF0IHRoZSBEdW5uIHRlc3QgKGluIHRoZSBGU0EgcGFja2FnZSkgaXMgYXBwcm9wcmlhdGUgZm9yIGdyb3VwcyB3aXRoIHVuZXF1YWwgbnVtYmVycyBvZiBvYnNlcnZhdGlvbnMuKFphciwgSi5ILiAyMDEwLiBCaW9zdGF0aXN0aWNhbCBBbmFseXNpcywgNXRoIGVkLiAgUGVhcnNvbiBQcmVudGljZSBIYWxsOiBVcHBlciBTYWRkbGUgUml2ZXIsIE5KLikgaHR0cDovL3Jjb21wYW5pb24ub3JnL3Jjb21wYW5pb24vZF8wNi5odG1sDQoNClNBTSBXSEVOIERVTk4gSVMgSU5TVEFMTEVELCBHTyBUTyBSQ09NUEFOSU9OUy5PUkcgQU5EIExPT0sgRk9SIERVTk4gLSBDSEVDSyBDSFJPTUUgSElTVE9SWSAoUFJPQkFCTFkgVU5ERVIgS1JVU0tBTCBXQUxMSVMpIEFMU08gTUFQIFRIRSBESVNUUklCVVRJT04gT0YgVEhFU0UgR0VBUiBUWVBFUw0KYGBge3J9DQpwYWlyd2lzZS53aWxjb3gudGVzdChwcmVzZW5jZSR0ZW1wX2RlcHRoLCBwcmVzZW5jZSRnZWFyLCBwLmFkaj0nYm9uZmVycm9uaScsIGV4YWN0PUYpDQpgYGANCg0KZHVubiB0ZXN0IA0KYGBge3J9DQpnZWFyX3RlbXBfZGVwdGhkdW5uIDwtIGR1bm5UZXN0KHByZXNlbmNlJHRlbXBfZGVwdGgsIHByZXNlbmNlJGdlYXIsIGxpc3QgPSBUUlVFKQ0KZ2Vhcl90ZW1wX2RlcHRoZHVubg0KDQoNCg0Kd3JpdGUuY3N2KHRhYmxlLCAiLi4vb3V0cHV0L2Vudi9nZWFyX3RlbXBfZGVwdGhkdW5uLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQpgYGANCg0KDQojdmlmDQoNCmZvciB0aGlzIHlvdSBuZWVkIHRoZSBqb2luZWQgZGF0YXNldC4gDQoNCmBgYHtyfQ0KdmlmX2FsbHByZXNhYiA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxwcmVzYWIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxscHJlc2FiLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxscHJlc2FiDQpgYGANCmludGVycHJldCAtIHNlZSBodHRwczovL3N0YXRzLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy83MDY3OS93aGljaC12YXJpYW5jZS1pbmZsYXRpb24tZmFjdG9yLXNob3VsZC1pLWJlLXVzaW5nLXRleHRndmlmLW9yLXRleHRndmlmLzk2NTg0Izk2NTg0DQpUbyBtYWtlIEdWSUZzIGNvbXBhcmFibGUgYWNyb3NzIGRpbWVuc2lvbnMsIHdlIHN1Z2dlc3RlZCB1c2luZyBHVklGXigxLygyKkRmKSksIHdoZXJlIERmIGlzIHRoZSBudW1iZXIgb2YgY29lZmZpY2llbnRzIGluIHRoZSBzdWJzZXQgKHJlZiBmb3ggYW5kIG1vdGV0dGUgMTk5MiBpbiB6b3Rlcm8pDQpvciB0aGUgMiBjb250aW51b3VzIHZhcmlhYmxlcywgR1ZJRsuGKDEvKDIqRGYpKSAod2hpY2ggaXMgYmFzaWNhbGx5IHRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgVklGL0dWSUYgdmFsdWUgYXMgREY9MSkgaXMgdGhlIHByb3BvcnRpb25hbCBjaGFuZ2Ugb2YgdGhlIHN0YW5kYXJkIGVycm9yIGFuZCBjb25maWRlbmNlIGludGVydmFsIG9mIHRoZWlyIGNvZWZmaWNpZW50cyBkdWUgdG8gdGhlIGxldmVsIG9mIGNvbGxpbmVhcml0eS4gVGhlIEdWSUbLhigxLygyKkRmKSkgdmFsdWUgb2YgdGhlIGNhdGVnb3JpY2FsIHZhcmlhYmxlIGlzIGEgc2ltaWxhciBtZWFzdXJlIGZvciB0aGUgcmVkdWN0aW9uIGluIHByZWNpc2lvbiBvZiB0aGUgY29lZmZpY2llbnRzJyBlc3RpbWF0aW9uIGR1ZSB0byBjb2xsaW5lYXJpdHkuIA0KYXBwYXJlbnRseSBpIGp1c3QgbmVlZCB0byBzcXVhcmUgR1ZJRl4oMS8oMipEZikpIGFuZCB0aGVuIHVzZSB0aGUgbm9ybWFsIFZJRiAicnVsZSBvZiB0aHVtYiIuLi4NCg0KYGBge3J9DQp2aWZfYWxscHJlc2FiX3NxIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxscHJlc2FiLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxscHJlc2FiX3NxJEdWSUYyRGZzcSA8LSB2aWZfYWxscHJlc2FiX3NxJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2FsbHByZXNhYl9zcSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxwcmVzYWIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxwcmVzYWJfc3ENCmBgYA0KDQpBcyBwZXIgU0xSIHN1Z2dlc3Rpb24sIHJlcnVuIHdpdGhvdXQgZ2Vhcg0KDQpgYGB7ciB2aWYgYWxsIGJ1dCBnZWFyfQ0KdmlmX2FsbGJ1dGdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRnZWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dGdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRnZWFyDQpgYGANCnh4DQpBcyBwZXIgU0xSIHN1Z2dlc3Rpb24sIHJlcnVuIHdpdGhvdXQgZ2VhciBhbmQgbW9zdCBoaWdobHkgY29ycmVsYXRlZCB2YXJpYWJsZXMgDQoNCmBgYHtyIHZpZiB3aXRob3V0IGdlYXIgKyBoaWdoIGNvcnJ9DQp2aWZfYWxsYnV0Z2VhcmhpZ2hseWNvcnIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG1scF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0Z2VhcmhpZ2hseWNvcnIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0Z2VhcmhpZ2hseWNvcnIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRnZWFyaGlnaGx5Y29ycg0KYGBgDQoNCg0KQXMgcGVyIFNMUiBzdWdnZXN0aW9uLCByZXJ1biB3aXRoIGdlYXIgYnV0IHdpdGhvdXQgbW9zdCBoaWdobHkgY29ycmVsYXRlZCB2YXJpYWJsZXMNCg0KYGBge3IgdmlmIGFsbCBidXQgaGlnaCBjb3JyfQ0KdmlmX2FsbGJ1dGhpZ2hseWNvcnIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG1scF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyICsgZ2VhciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGhpZ2hseWNvcnIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0aGlnaGx5Y29yci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dGhpZ2hseWNvcnINCg0KdmlmX2FsbGJ1dGhpZ2hseWNvcnJfc3EgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdobHljb3JyLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGx5Y29ycl9zcSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dGhpZ2hseWNvcnJfc3EkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGx5Y29ycl9zcSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdobHljb3JyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGx5Y29ycl9zcQ0KYGBgDQoNCm9rIHJlbW92ZSBvbmUgdmFyaWFibGUgYXQgYSB0aW1lIC0gbGVhdmUgZ2VhciBpbg0KDQpyZW1vdmUgYm90dG9tX2RlcHRoDQpgYGB7ciB2aWYgYWxsIGJ1dCBib3RkZXB0aH0NCnZpZl9hbGxidXRib3RfcHJldiA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRib3RfcHJldiwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRib3RfcHJldi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfYWxsYnV0Ym90X3ByZXYgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRib3RfcHJldi5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2FsbGJ1dGJvdF9wcmV2JEdWSUYyRGZzcSA8LSB2aWZfYWxsYnV0Ym90X3ByZXYkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0Ym90X3ByZXYsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0Ym90X3ByZXYuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRib3RfcHJldg0KYGBgDQoNCmFuZCBsZWF2ZSBnZWFyIG91dA0KDQpyZW1vdmUgYm90dG9tX2RlcHRoICsgZ2Vhcg0KYGBge3IgdmlmIGFsbCBidXQgYm90ZGRlcHRoICsgZ2Vhcn0NCnZpZl9hbGxidXRib3RfcHJldmdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRib3RfcHJldmdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0Ym90X3ByZXZnZWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0Ym90X3ByZXZnZWFyDQpgYGANCg0KcmVtb3ZlIGFtb19wcmV2DQpgYGB7ciB2aWYgYWxsIGJ1dCBhbW9wcmV2fQ0KdmlmX2FsbGJ1dGFtb19wcmV2IDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRhbW9fcHJldiwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRhbW9fcHJldi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfYWxsYnV0YW1vX3ByZXYgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRhbW9fcHJldi5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2FsbGJ1dGFtb19wcmV2JEdWSUYyRGZzcSA8LSB2aWZfYWxsYnV0YW1vX3ByZXYkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0YW1vX3ByZXYsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0YW1vX3ByZXYuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRhbW9fcHJldg0KYGBgDQphbmQgbGVhdmUgZ2VhciBvdXQNCg0KcmVtb3ZlIGFtb19wcmV2ICsgZ2Vhcg0KYGBge3IgdmlmIGFsbCBidXQgYW1vcHJldiArIGdlYXJ9DQp2aWZfYWxsYnV0YW1vX3ByZXZnZWFyIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGFtb19wcmV2Z2VhciwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRhbW9fcHJldmdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRhbW9fcHJldmdlYXINCmBgYA0KDQpyZW1vdmUgY2hsX2RlcHRoDQpgYGB7ciB2aWYgYWxsIGJ1dCBjaGxkZXB0aH0NCnZpZl9hbGxidXRjaGxfZGVwdGggPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0Y2hsX2RlcHRoLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dGNobF9kZXB0aC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfYWxsYnV0Y2hsX2RlcHRoIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0Y2hsX2RlcHRoLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0Y2hsX2RlcHRoJEdWSUYyRGZzcSA8LSB2aWZfYWxsYnV0Y2hsX2RlcHRoJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2FsbGJ1dGNobF9kZXB0aCwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRjaGxfZGVwdGguY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRjaGxfZGVwdGgNCmBgYA0KDQpyZW1vdmUgY2hsX2RlcHRoIGFuZCBnZWFyDQpgYGB7ciB2aWYgYWxsIGJ1dCBjaGxkZXB0aCtnZWFyfQ0KdmlmX2FsbGJ1dGNobF9kZXB0aGdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRjaGxfZGVwdGhnZWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dGNobF9kZXB0aGdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRjaGxfZGVwdGhnZWFyDQpgYGANCg0KDQpyZW1vdmUgc3NoX3N1cmZhY2UNCmBgYHtyIHZpZiBhbGwgYnV0IHNzaH0NCnZpZl9hbGxidXRzc2hfc3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0c3NoX3N1cmZhY2UsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0c3NoX3N1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2FsbGJ1dHNzaF9zdXJmYWNlIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0c3NoX3N1cmZhY2UuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9hbGxidXRzc2hfc3VyZmFjZSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dHNzaF9zdXJmYWNlJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHNzaF9zdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHNzaF9zdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0c3NoX3N1cmZhY2UNCmBgYA0KDQpyZW1vdmUgc3NoX3N1cmZhY2UgJiBnZWFyDQpgYGB7ciB2aWYgYWxsIGJ1dCBzc2grZ2Vhcn0NCnZpZl9hbGxidXRzc2hfc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0c3NoX3N1cmZhY2VnZWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHNzaF9zdXJmYWNlZ2Vhci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dHNzaF9zdXJmYWNlZ2Vhcg0KYGBgDQoNCnJlbW92ZSBvMl9zdXJmYWNlDQpgYGB7ciB2aWYgYWxsIGJ1dCBvMnN1cmZhY2V9DQp2aWZfYWxsYnV0bzJfc3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dG8yX3N1cmZhY2UsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0bzJfc3VyZmFjZS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfYWxsYnV0bzJfc3VyZmFjZSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dG8yX3N1cmZhY2UuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9hbGxidXRvMl9zdXJmYWNlJEdWSUYyRGZzcSA8LSB2aWZfYWxsYnV0bzJfc3VyZmFjZSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxidXRvMl9zdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dG8yX3N1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRvMl9zdXJmYWNlDQpgYGANCg0KcmVtb3ZlIG8yX3N1cmZhY2UgJiBnZWFyDQpgYGB7ciB2aWYgYWxsIGJ1dCBvMnN1cmZhY2UrZ2Vhcn0NCnZpZl9hbGxidXRvMl9zdXJmYWNlZ2VhciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0bzJfc3VyZmFjZWdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0bzJfc3VyZmFjZWdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRvMl9zdXJmYWNlZ2Vhcg0KYGBgDQoNCmFzIHBlciBTTFIgY2hhdCBqYW4gMjM6IA0KDQpyZW1vdmUgc2FsaW5pdHlfc3VyZmFjZSBvbmx5DQpgYGB7ciB2aWYgYWxsIGJ1dCBzYWxzdXJmYWNlfQ0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRzYWxpbml0eXN1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZS5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxidXRzYWxpbml0eXN1cmZhY2UsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlDQpgYGANCmFuZCB3aXRob3V0IGdlYXINCg0KYGBge3IgdmlmIGFsbCBidXQgc2Fsc3VyZmFjZStnZWFyfQ0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZWdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0c2FsaW5pdHlzdXJmYWNlZ2Vhci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dHNhbGluaXR5c3VyZmFjZWdlYXINCmBgYA0KDQpyZW1vdmUgdGVtcF9zdXJmYWNlIG9ubHkNCmBgYHtyIHZpZiBhbGwgYnV0IHRlbXBzdXJmYWNlfQ0KdmlmX2FsbGJ1dHRlbXBzdXJmYWNlIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHRlbXBzdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHRlbXBzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnZpZl9hbGxidXR0ZW1wc3VyZmFjZSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHRlbXBzdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0dGVtcHN1cmZhY2UkR1ZJRjJEZnNxIDwtIHZpZl9hbGxidXR0ZW1wc3VyZmFjZSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxidXR0ZW1wc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXR0ZW1wc3VyZmFjZS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dHRlbXBzdXJmYWNlDQoNCnZpZl9hbGxidXR0ZW1wc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXR0ZW1wc3VyZmFjZWdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0dGVtcHN1cmZhY2VnZWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0dGVtcHN1cmZhY2VnZWFyDQoNCmBgYA0KDQpub3cgcmVtb3ZlIHRlbXBfc3VyZmFjZSBwbHVzIGhpZ2hseSBjb3JyZWxhdGVkDQpgYGB7ciB2aWYgYWxsYnV0IGhpZ2ggY29yciArIHRlbXAgc3VyZmFjZS9nZWFyL25vZ2Vhcn0NCiN3aXRoIGdlYXINCnZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBtbHBfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHN1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHN1cmZhY2UgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHN1cmZhY2UkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZQ0KDQojd2l0aG91dCBnZWFyDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG1scF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZWdlYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc3VyZmFjZWdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXRoaWdoY29ycnRlbXBzdXJmYWNlZ2Vhcg0KYGBgDQoNCm5vdyByZW1vdmUgdGVtcF9zdXJmYWNlIHBsdXMgc2FsaW5pdHlfc3VyZmFjZQ0KYGBge3IgdmlmIGFsbGJ1dCB0ZW1wICsgc2FsaW5pdHkgc3VyZmFjZS9nZWFyL25vZ2Vhcn0NCiN3aXRoIGdlYXINCnZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZSA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0dGVtcHNhbHN1cmZhY2UkR1ZJRjJEZnNxIDwtIHZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZSRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlDQoNCiN3aXRob3V0IGdlYXINCnZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2FsbGJ1dHRlbXBzYWxzdXJmYWNlZ2VhciwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZWdlYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9hbGxidXR0ZW1wc2Fsc3VyZmFjZWdlYXINCmBgYA0KDQpub3cgcmVtb3ZlIHRlbXBfc3VyZmFjZSBwbHVzIHNhbGluaXR5X3N1cmZhY2UgKyBoaWdobHkgY29ycmVsYXRlZA0KYGBge3IgdmlmIGFsbGJ1dCBoaWdoIGNvcnIgKyAgdGVtcCArIHNhbGluaXR5IHN1cmZhY2UvZ2Vhci9ub2dlYXJ9DQojd2l0aCBnZWFyDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBtbHBfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2UuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2UgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZSRHVklGMkRmc3EgPC0gdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2UkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZSwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZQ0KDQojd2l0aG91dCBnZWFyDQp2aWZfYWxsYnV0aGlnaGNvcnJ0ZW1wc2Fsc3VyZmFjZWdlYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgbWxwX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlZ2VhciwgIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRoaWdoY29ycnRlbXBzYWxzdXJmYWNlZ2Vhci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dGhpZ2hjb3JydGVtcHNhbHN1cmZhY2VnZWFyDQpgYGANCg0KSnVzdCBvdXQgb2YgY3VyaW9zaXR5LCBhIHZpZiB3aWxsIGFsbCBidXQgYnV0IGF0bW9zIGRyaXZlcnMNCg0KYGBge3J9DQp2aWZfYWxsYnV0bmFvYW1vIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIsIGRhdGEgPSBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9hbGxidXRuYW9hbW8sICIuLi9vdXRwdXQvYmlvL3ZpZi92aWZfYWxsYnV0bmFvYW1vLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnZpZl9hbGxidXRuYW9hbW8gPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL3ZpZl9hbGxidXRuYW9hbW8uY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9hbGxidXRuYW9hbW8kR1ZJRjJEZnNxIDwtIHZpZl9hbGxidXRuYW9hbW8kR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfYWxsYnV0bmFvYW1vLCAiLi4vb3V0cHV0L2Jpby92aWYvdmlmX2FsbGJ1dG5hb2Ftby5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2FsbGJ1dG5hb2Ftbw0KYGBgDQpub3QgbXVjaCBkaWZmLi4NCg0KIyBtb250aGx5IHNwZWFybWFucyBjb3JyZWxhdGlvbnMgYW5kIFZJRg0KDQpjdXJpb3VzIC0gZG9lcyBjb3JyZWxhdGlvbnMvdmlmIGFsdGVyIGJldHdlZW4gbW9udGhzPw0KDQpGaXJzdCBzcGxpdCB0aGUgZGF0YXNldCBpbnRvIG1vbnRobHkNCg0KYGBge3Igc3Vic2V0IG1vbnRobHkgcHJlc2FifQ0KcHJlc2FiJGdlYXIgPC0gYXMuY2hhcmFjdGVyKHByZXNhYiRnZWFyKQ0KamFucHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICIxIikNCmZlYnByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiMiIpDQptYXJwcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjMiKQ0KYXBycHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICI0IikNCm1heXByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiNSIpDQpqdW5wcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjYiKQ0KanVscHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICI3IikNCmF1Z3ByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiOCIpDQpzZXBwcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjkiKQ0Kb2N0cHJlc2FiIDwtIHN1YnNldChwcmVzYWIsIG1vbnRoID09ICIxMCIpDQpub3ZwcmVzYWIgPC0gc3Vic2V0KHByZXNhYiwgbW9udGggPT0gIjExIikNCmRlY3ByZXNhYiA8LSBzdWJzZXQocHJlc2FiLCBtb250aCA9PSAiMTIiKQ0KYGBgDQoNCm5vdyBnZXQgdGhlIGJhY2tncm91bmQgcG9pbnRzIGZvciBlYWNoIG1vbnRoIChmb3Igc3BlYXJtYW5zKQ0KYGBge3IgbW9udGhseSBiYWNrZ3JvdW5kIHBvaW50c30NCmphbmJhY2sgPC0gc3Vic2V0KGphbnByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQpmZWJiYWNrIDwtIHN1YnNldChmZWJwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0KbWFyYmFjayA8LSBzdWJzZXQobWFycHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCmFwcmJhY2sgPC0gc3Vic2V0KGFwcnByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQptYXliYWNrIDwtIHN1YnNldChtYXlwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0KanVuYmFjayA8LSBzdWJzZXQoanVucHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCmp1bGJhY2sgPC0gc3Vic2V0KGp1bHByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQphdWdiYWNrIDwtIHN1YnNldChhdWdwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0Kc2VwYmFjayA8LSBzdWJzZXQoc2VwcHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCm9jdGJhY2sgPC0gc3Vic2V0KG9jdHByZXNhYiwgb2NjdXJyZW5jZSA9PSAiMCIpDQpub3ZiYWNrIDwtIHN1YnNldChub3ZwcmVzYWIsIG9jY3VycmVuY2UgPT0gIjAiKQ0KZGVjYmFjayA8LSBzdWJzZXQoZGVjcHJlc2FiLCBvY2N1cnJlbmNlID09ICIwIikNCmBgYA0KDQpydW4gdGhlIGNvcnJlbGF0aW9ucyBvbiBlYWNoIG1vbnRoJ3MgYmFja2dyb3VuZCBwb2ludHMNCg0KYGBge3IgbW9udGhseSBzcGVhcm1hbiBjb3JyZWxhdGlvbnN9DQpqYW5iYWNrIDwtIHN1YnNldChqYW5iYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCmphbmJhY2tfY29yIDwtIGNvcihqYW5iYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihqYW5iYWNrX2NvciwgIi4uL291dHB1dC9lbnYvamFuYmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KZmViYmFjayA8LSBzdWJzZXQoZmViYmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQpmZWJiYWNrX2NvciA8LSBjb3IoZmViYmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3YoZmViYmFja19jb3IsICIuLi9vdXRwdXQvZW52L2ZlYmJhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCm1hcmJhY2sgPC0gc3Vic2V0KG1hcmJhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoLCBib3R0b21fZGVwdGgpKQ0KbWFyYmFja19jb3IgPC0gY29yKG1hcmJhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KG1hcmJhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9tYXJiYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQphcHJiYWNrIDwtIHN1YnNldChhcHJiYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCmFwcmJhY2tfY29yIDwtIGNvcihhcHJiYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihhcHJiYWNrX2NvciwgIi4uL291dHB1dC9lbnYvYXByYmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KbWF5YmFjayA8LSBzdWJzZXQobWF5YmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQptYXliYWNrX2NvciA8LSBjb3IobWF5YmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3YobWF5YmFja19jb3IsICIuLi9vdXRwdXQvZW52L21heWJhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCmp1bmJhY2sgPC0gc3Vic2V0KGp1bmJhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoLCBib3R0b21fZGVwdGgpKQ0KanVuYmFja19jb3IgPC0gY29yKGp1bmJhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KGp1bmJhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9qdW5iYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQpqdWxiYWNrIDwtIHN1YnNldChqdWxiYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCmp1bGJhY2tfY29yIDwtIGNvcihqdWxiYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihqdWxiYWNrX2NvciwgIi4uL291dHB1dC9lbnYvanVsYmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KYXVnYmFjayA8LSBzdWJzZXQoYXVnYmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQphdWdiYWNrX2NvciA8LSBjb3IoYXVnYmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3YoYXVnYmFja19jb3IsICIuLi9vdXRwdXQvZW52L2F1Z2JhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnNlcGJhY2sgPC0gc3Vic2V0KHNlcGJhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoLCBib3R0b21fZGVwdGgpKQ0Kc2VwYmFja19jb3IgPC0gY29yKHNlcGJhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KHNlcGJhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9zZXBiYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQpvY3RiYWNrIDwtIHN1YnNldChvY3RiYWNrLCBzZWxlY3QgPSBjKGFtb19zYW1wbGUsIGFtb193aW50ZXIsIGFtb19wcmV2LCBuYW9fc2FtcGxlLCBuYW9fd2ludGVyLCBuYW9fcHJldiwgY2hsX3N1cmZhY2UsIGNobF9kZXB0aCwgbWxwX3N1cmZhY2UsIHNzaF9zdXJmYWNlLCB0ZW1wX3N1cmZhY2UsIHRlbXBfZGVwdGgsIG8yX3N1cmZhY2UsIG8yX2RlcHRoLCBzYWxpbml0eV9zdXJmYWNlLCBzYWxpbml0eV9kZXB0aCwgYm90dG9tX2RlcHRoKSkNCm9jdGJhY2tfY29yIDwtIGNvcihvY3RiYWNrLCB1c2U9ImNvbXBsZXRlLm9icyIsIG1ldGhvZCA9ICJzcGVhcm1hbiIpICNuZWVkIHRvIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIHVzaW5nIGNvciB0byBwbG90LiBjb21wbGV0ZS5vYnMgbWVhbnMgbmEucm0gaW4gdGhpcyBwYWNrYWdlLiAjdXNpbmcgc3BlYXJtYW5zIGFzIHN1aXRhYmxlIGZvciBub24tbGluZWFyIHJlbGF0aW9uc2hpcHMNCndyaXRlLmNzdihvY3RiYWNrX2NvciwgIi4uL291dHB1dC9lbnYvb2N0YmFja19jb3IuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0Kbm92YmFjayA8LSBzdWJzZXQobm92YmFjaywgc2VsZWN0ID0gYyhhbW9fc2FtcGxlLCBhbW9fd2ludGVyLCBhbW9fcHJldiwgbmFvX3NhbXBsZSwgbmFvX3dpbnRlciwgbmFvX3ByZXYsIGNobF9zdXJmYWNlLCBjaGxfZGVwdGgsIG1scF9zdXJmYWNlLCBzc2hfc3VyZmFjZSwgdGVtcF9zdXJmYWNlLCB0ZW1wX2RlcHRoLCBvMl9zdXJmYWNlLCBvMl9kZXB0aCwgc2FsaW5pdHlfc3VyZmFjZSwgc2FsaW5pdHlfZGVwdGgsIGJvdHRvbV9kZXB0aCkpDQpub3ZiYWNrX2NvciA8LSBjb3Iobm92YmFjaywgdXNlPSJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAic3BlYXJtYW4iKSAjbmVlZCB0byBjcmVhdGUgYSBjb3JyZWxhdGlvbiB1c2luZyBjb3IgdG8gcGxvdC4gY29tcGxldGUub2JzIG1lYW5zIG5hLnJtIGluIHRoaXMgcGFja2FnZS4gI3VzaW5nIHNwZWFybWFucyBhcyBzdWl0YWJsZSBmb3Igbm9uLWxpbmVhciByZWxhdGlvbnNoaXBzDQp3cml0ZS5jc3Yobm92YmFja19jb3IsICIuLi9vdXRwdXQvZW52L25vdmJhY2tfY29yLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCmRlY2JhY2sgPC0gc3Vic2V0KGRlY2JhY2ssIHNlbGVjdCA9IGMoYW1vX3NhbXBsZSwgYW1vX3dpbnRlciwgYW1vX3ByZXYsIG5hb19zYW1wbGUsIG5hb193aW50ZXIsIG5hb19wcmV2LCBjaGxfc3VyZmFjZSwgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgdGVtcF9kZXB0aCwgbzJfc3VyZmFjZSwgbzJfZGVwdGgsIHNhbGluaXR5X3N1cmZhY2UsIHNhbGluaXR5X2RlcHRoLCBib3R0b21fZGVwdGgpKQ0KZGVjYmFja19jb3IgPC0gY29yKGRlY2JhY2ssIHVzZT0iY29tcGxldGUub2JzIiwgbWV0aG9kID0gInNwZWFybWFuIikgI25lZWQgdG8gY3JlYXRlIGEgY29ycmVsYXRpb24gdXNpbmcgY29yIHRvIHBsb3QuIGNvbXBsZXRlLm9icyBtZWFucyBuYS5ybSBpbiB0aGlzIHBhY2thZ2UuICN1c2luZyBzcGVhcm1hbnMgYXMgc3VpdGFibGUgZm9yIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwcw0Kd3JpdGUuY3N2KGRlY2JhY2tfY29yLCAiLi4vb3V0cHV0L2Vudi9kZWNiYWNrX2Nvci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KYGBgDQoNClJ1biBhIFZJRiBmb3IgZWFjaCBtb250aCAod2l0aCBhbmQgd2l0aG91dCBnZWFyKQ0KDQpgYGB7ciBtb250aGx5IHZpZiB3aXRoIGFuZCB3aXRob3V0IGdlYXJ9DQoNCg0KI3dpdGggZ2VhciAtIGZvciBqYW4gdGhlcmUgaXMgbm9uZSBiZWNhdXNlIHRoZXJlIGlzIG9ubHkgb25lIGNhdGVnb3J5IG9mIGdlYXINCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9qYW4gPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlLCBkYXRhID0gamFucHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2phbiwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2phbi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9qYW4NCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9mZWIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlLCBkYXRhID0gZmVicHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2ZlYiwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2ZlYi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9mZWINCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfbWFyIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IG1hcnByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfbWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX21hci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfbWFyDQoNCnZpZl9nZWFyX21hciA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX21hci5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2dlYXJfbWFyJEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9tYXIkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfZ2Vhcl9tYXIsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfbWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9tYXINCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9tYXIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBtYXJwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfbWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfbWFyLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX21hcg0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9hcHIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gYXBycHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9hcHIsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfYXByLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9hcHINCg0KdmlmX2dlYXJfYXByIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfYXByLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9hcHIkR1ZJRjJEZnNxIDwtIHZpZl9nZWFyX2FwciRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9nZWFyX2FwciwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9hcHIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2Fwcg0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2FwciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IGFwcnByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9hcHIsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9hcHIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfYXByDQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX21heSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBtYXlwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX21heSwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9tYXkuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX21heQ0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX21heSA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IG1heXByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9tYXksICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9tYXkuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfbWF5DQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX2p1biA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBqdW5wcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX2p1biwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9qdW4uY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2p1bg0KDQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfanVuIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0ganVucHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2p1biwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2p1bi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9qdW4NCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfanVsIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IGp1bHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfanVsLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2p1bC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfanVsDQoNCnZpZl9nZWFyX2p1bCA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2p1bC5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2dlYXJfanVsJEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9qdWwkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfZ2Vhcl9qdWwsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfanVsLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9qdWwNCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9qdWwgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBqdWxwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfanVsLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfanVsLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2p1bA0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9hdWcgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gYXVncHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9hdWcsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfYXVnLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9hdWcNCg0KdmlmX2dlYXJfYXVnIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfYXVnLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9hdWckR1ZJRjJEZnNxIDwtIHZpZl9nZWFyX2F1ZyRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9nZWFyX2F1ZywgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9hdWcuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2F1Zw0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2F1ZyA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IGF1Z3ByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9hdWcsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9hdWcuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfYXVnDQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX3NlcCA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBzZXBwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX3NlcCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9zZXAuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX3NlcA0KDQp2aWZfZ2Vhcl9zZXAgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9zZXAuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9nZWFyX3NlcCRHVklGMkRmc3EgPC0gdmlmX2dlYXJfc2VwJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2dlYXJfc2VwLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX3NlcC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfc2VwDQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfc2VwIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gc2VwcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX3NlcCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX3NlcC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9zZXANCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfb2N0IDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9zdXJmYWNlICsgdGVtcF9kZXB0aCArIHNhbGluaXR5X3N1cmZhY2UgKyBzYWxpbml0eV9kZXB0aCArIG8yX3N1cmZhY2UgKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgY2hsX2RlcHRoICsgYm90dG9tX2RlcHRoICsgbWxwX3N1cmZhY2UgKyBzc2hfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IG9jdHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfb2N0LCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX29jdC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfb2N0DQoNCnZpZl9nZWFyX29jdCA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX29jdC5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2dlYXJfb2N0JEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9vY3QkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfZ2Vhcl9vY3QsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfb2N0LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9vY3QNCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9vY3QgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBvY3RwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfb2N0LCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfb2N0LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX29jdA0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9ub3YgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3ByZXYgKyBhbW9fd2ludGVyLCBkYXRhID0gbm92cHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9ub3YsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfbm92LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9ub3YNCg0KdmlmX2dlYXJfbm92IDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfbm92LmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9ub3YkR1ZJRjJEZnNxIDwtIHZpZl9nZWFyX25vdiRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9nZWFyX25vdiwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9ub3YuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX25vdg0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX25vdiA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IG5vdnByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9ub3YsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9ub3YuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfbm92DQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX2RlYyA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfc3VyZmFjZSArIHRlbXBfZGVwdGggKyBzYWxpbml0eV9zdXJmYWNlICsgc2FsaW5pdHlfZGVwdGggKyBvMl9zdXJmYWNlICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGNobF9kZXB0aCArIGJvdHRvbV9kZXB0aCArIG1scF9zdXJmYWNlICsgc3NoX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb19wcmV2ICsgYW1vX3dpbnRlciwgZGF0YSA9IGRlY3ByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfZGVjLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2RlYy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfZGVjDQoNCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9kZWMgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX3N1cmZhY2UgKyB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfc3VyZmFjZSArIHNhbGluaXR5X2RlcHRoICsgbzJfc3VyZmFjZSArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBjaGxfZGVwdGggKyBib3R0b21fZGVwdGggKyBtbHBfc3VyZmFjZSArIHNzaF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fcHJldiArIGFtb193aW50ZXIsIGRhdGEgPSBkZWNwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfZGVjLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfZGVjLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2RlYw0KYGBgDQoNCnNwZWFybWFucyBpbmRpY2F0ZXMgY2hsX2RlcHRoLCBtbHBfc3VyZmFjZSwgc3NoX3N1cmZhY2UsIHRlbXBfc3VyZmFjZSwgbzJfc3VyZmFjZSwgc2FsaW5pdHlfc3VyZmFjZSwgYW5kIGJvdHRvbV9kZXB0aCwgYW1vX3ByZXYgKGFuZCBmb3IgSnVuIGFuZCBPY3QgY2hsX3N1cmZhY2U7IGFuZCBmb3IgamFuIGFtb193aW50ZXIsIGFtcG9fcHJldiwgYW1vX3NhbXBsZSwgYW5kIE5BT19wcmV2LCBhbmQgZmViIGFtb193aW50ZXIsIGFtcG9fcHJldiwgYW1vX3NhbXBsZSwgbmFvIHdpbnRlciwgYW5kIE5BT19wcmV2KSBhbGwgIGNvcnJlbGF0ZWQgZXZlcnkgbW9udGguIHJlbW92ZSBmcm9tIGVhY2ggbW9kZWwgYW5kIHJlcnVuDQpSdW4gYSBWSUYgZm9yIGVhY2ggbW9udGggKHdpdGggYW5kIHdpdGhvdXQgZ2VhcikNCg0KYGBge3IgbW9udGhseSB2aWYgd2l0aCBhbmQgd2l0aG91dCBnZWFyIGFuZCBoaWdobHkgY29ycmVsYXRlZH0NCg0KDQojd2l0aCBnZWFyIC0gZm9yIGphbiB0aGVyZSBpcyBub25lIGJlY2F1c2UgdGhlcmUgaXMgb25seSBvbmUgY2F0ZWdvcnkgb2YgZ2Vhcg0KDQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfY29yX2phbiA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UrIG5hb19zYW1wbGUgKyBuYW9fd2ludGVyLCBkYXRhID0gamFucHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9qYW4sICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3JfamFuLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9qYW4NCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9jb3JfZmViIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSAgKyBuYW9fc2FtcGxlLCBkYXRhID0gZmVicHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9mZWIsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3JfZmViLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9mZWINCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfY29yX21hciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gbWFycHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3JfbWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9tYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2dlYXJfY29yX21hciA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9tYXIuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9tYXIkR1ZJRjJEZnNxIDwtIHZpZl9nZWFyX2Nvcl9tYXIkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3JfbWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9tYXIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9tYXINCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9jb3JfbWFyIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IG1hcnByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9jb3JfbWFyLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfY29yX21hci5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9jb3JfbWFyDQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX2Nvcl9hcHIgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IGFwcnByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX2FwciwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfYXByLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnZpZl9nZWFyX2Nvcl9hcHIgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfYXByLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3JfYXByJEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9jb3JfYXByJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX2FwciwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfYXByLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3JfYXByDQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfY29yX2FwciA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBhcHJwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfY29yX2FwciwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2Nvcl9hcHIuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfY29yX2Fwcg0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9jb3JfbWF5IDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBtYXlwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX2Nvcl9tYXksICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX21heS5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2Nvcl9tYXkgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gbWF5cHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9tYXksICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3JfbWF5LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9tYXkNCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfY29yX2p1biA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0ganVucHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3JfanVuLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9qdW4uY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9qdW4NCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9jb3JfanVuIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IGp1bnByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9jb3JfanVuLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfY29yX2p1bi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9jb3JfanVuDQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX2Nvcl9qdWwgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IGp1bHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX2p1bCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfanVsLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQoNCnZpZl9nZWFyX2Nvcl9qdWwgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfanVsLmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3JfanVsJEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9jb3JfanVsJEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX2p1bCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3JfanVsLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3JfanVsDQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfY29yX2p1bCA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBqdWxwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfY29yX2p1bCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2Nvcl9qdWwuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfY29yX2p1bA0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9jb3JfYXVnIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBhdWdwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX2Nvcl9hdWcsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX2F1Zy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfZ2Vhcl9jb3JfYXVnIDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX2F1Zy5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2dlYXJfY29yX2F1ZyRHVklGMkRmc3EgPC0gdmlmX2dlYXJfY29yX2F1ZyRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9nZWFyX2Nvcl9hdWcsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX2F1Zy5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfY29yX2F1Zw0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2Nvcl9hdWcgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gYXVncHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9hdWcsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3JfYXVnLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9hdWcNCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfY29yX3NlcCA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gc2VwcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3Jfc2VwLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9zZXAuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCg0KdmlmX2dlYXJfY29yX3NlcCA8LSByZWFkLmNzdigiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9zZXAuY3N2IiwgaGVhZGVyID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9zZXAkR1ZJRjJEZnNxIDwtIHZpZl9nZWFyX2Nvcl9zZXAkR1ZJRi4uMS4uMi5EZi4uXjINCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3Jfc2VwLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9zZXAuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9zZXANCg0KI3dpdGhvdXQgZ2Vhcg0KdmlmX25vZ2Vhcl9jb3Jfc2VwIDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IHNlcHByZXNhYikpDQp3cml0ZS5jc3YodmlmX25vZ2Vhcl9jb3Jfc2VwLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9ub2dlYXJfY29yX3NlcC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX25vZ2Vhcl9jb3Jfc2VwDQoNCiN3aXRoIGdlYXINCnZpZl9nZWFyX2Nvcl9vY3QgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgZ2VhciArIG5hb19zYW1wbGUgKyBuYW9fcHJldiArIG5hb193aW50ZXIgKyBhbW9fc2FtcGxlICsgYW1vX3dpbnRlciwgZGF0YSA9IG9jdHByZXNhYikpDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX29jdCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3Jfb2N0LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3Jfb2N0DQoNCnZpZl9nZWFyX2Nvcl9vY3QgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3Jfb2N0LmNzdiIsIGhlYWRlciA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3Jfb2N0JEdWSUYyRGZzcSA8LSB2aWZfZ2Vhcl9jb3Jfb2N0JEdWSUYuLjEuLjIuRGYuLl4yDQp3cml0ZS5jc3YodmlmX2dlYXJfY29yX29jdCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfZ2Vhcl9jb3Jfb2N0LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfZ2Vhcl9jb3Jfb2N0DQoNCiN3aXRob3V0IGdlYXINCnZpZl9ub2dlYXJfY29yX29jdCA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBvY3RwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9ub2dlYXJfY29yX29jdCwgIi4uL291dHB1dC9iaW8vdmlmL21vbnRobHlfdmlmcy92aWZfbm9nZWFyX2Nvcl9vY3QuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9ub2dlYXJfY29yX29jdA0KDQojd2l0aCBnZWFyDQp2aWZfZ2Vhcl9jb3Jfbm92IDwtIHZpZihsbShvY2N1cnJlbmNlIH4gdGVtcF9kZXB0aCArIHNhbGluaXR5X2RlcHRoICsgbzJfZGVwdGggKyBjaGxfc3VyZmFjZSArIGdlYXIgKyBuYW9fc2FtcGxlICsgbmFvX3ByZXYgKyBuYW9fd2ludGVyICsgYW1vX3NhbXBsZSArIGFtb193aW50ZXIsIGRhdGEgPSBub3ZwcmVzYWIpKQ0Kd3JpdGUuY3N2KHZpZl9nZWFyX2Nvcl9ub3YsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX25vdi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KDQp2aWZfZ2Vhcl9jb3Jfbm92IDwtIHJlYWQuY3N2KCIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX25vdi5jc3YiLCBoZWFkZXIgPSBUUlVFKQ0KdmlmX2dlYXJfY29yX25vdiRHVklGMkRmc3EgPC0gdmlmX2dlYXJfY29yX25vdiRHVklGLi4xLi4yLkRmLi5eMg0Kd3JpdGUuY3N2KHZpZl9nZWFyX2Nvcl9ub3YsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX2dlYXJfY29yX25vdi5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQ0KdmlmX2dlYXJfY29yX25vdg0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2Nvcl9ub3YgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gbm92cHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9ub3YsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3Jfbm92LmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9ub3YNCg0KI3dpdGggZ2Vhcg0KdmlmX2dlYXJfY29yX2RlYyA8LSB2aWYobG0ob2NjdXJyZW5jZSB+IHRlbXBfZGVwdGggKyBzYWxpbml0eV9kZXB0aCArIG8yX2RlcHRoICsgY2hsX3N1cmZhY2UgKyBnZWFyICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gZGVjcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfZ2Vhcl9jb3JfZGVjLCAiLi4vb3V0cHV0L2Jpby92aWYvbW9udGhseV92aWZzL3ZpZl9nZWFyX2Nvcl9kZWMuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkNCnZpZl9nZWFyX2Nvcl9kZWMNCg0KDQojd2l0aG91dCBnZWFyDQp2aWZfbm9nZWFyX2Nvcl9kZWMgPC0gdmlmKGxtKG9jY3VycmVuY2UgfiB0ZW1wX2RlcHRoICsgc2FsaW5pdHlfZGVwdGggKyBvMl9kZXB0aCArIGNobF9zdXJmYWNlICsgbmFvX3NhbXBsZSArIG5hb19wcmV2ICsgbmFvX3dpbnRlciArIGFtb19zYW1wbGUgKyBhbW9fd2ludGVyLCBkYXRhID0gZGVjcHJlc2FiKSkNCndyaXRlLmNzdih2aWZfbm9nZWFyX2Nvcl9kZWMsICIuLi9vdXRwdXQvYmlvL3ZpZi9tb250aGx5X3ZpZnMvdmlmX25vZ2Vhcl9jb3JfZGVjLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpDQp2aWZfbm9nZWFyX2Nvcl9kZWMNCmBgYA0KDQppbiB0aGUgcHJlc2VuY2VzLCB3aGljaCByb3dzIGFyZSBtaXNzaW5nIGVpdGhlciB0ZW1wX2RlcHRoLCBzYWxpbml0eV9kZXB0aCwgb3IgbzJfZGVwdGg/DQpgYGB7cn0NCmZtYXRjaCgibzJfZGVwdGgiLCBuYW1lcyhwcmVzZW5jZSkpICMzMg0KZm1hdGNoKCJzYWxpbml0eV9kZXB0aCIsIG5hbWVzKHByZXNlbmNlKSkgIzM0DQpmbWF0Y2goInRlbXBfZGVwdGgiLCBuYW1lcyhwcmVzZW5jZSkpICMzNw0KYGBgDQpgYGB7cn0NCnByZXNlbmNlX3dkZXB0aF9ub28yIDwtIHByZXNlbmNlW2lzLm5hKHByZXNlbmNlJG8yX2RlcHRoKSwgXQ0KbnJvdyhwcmVzZW5jZV93ZGVwdGhfbm9vMikgI2p1c3QgdG8gY2hlY2sgaXQgaGFzIG1hcHBlZA0KcHJlc2VuY2Vfd2RlcHRoX25vc2FsaW5pdHkgPC0gcHJlc2VuY2VbaXMubmEocHJlc2VuY2Ukc2FsaW5pdHlfZGVwdGgpLCBdDQpucm93KHByZXNlbmNlX3dkZXB0aF9ub3NhbGluaXR5KSAjanVzdCB0byBjaGVjayBpdCBoYXMgbWFwcGVkDQpwcmVzZW5jZV93ZGVwdGhfbm90ZW1wIDwtIHByZXNlbmNlW2lzLm5hKHByZXNlbmNlJHRlbXBfZGVwdGgpLCBdDQpucm93KHByZXNlbmNlX3dkZXB0aF9ub3RlbXApICNqdXN0IHRvIGNoZWNrIGl0IGhhcyBtYXBwZWQNCmBgYA0KDQpvayByZW1vdmUgYWxsIHJvd3Mgd2hlcmUgdGVtcF9kZXB0aCBpcyBtaXNzaW5nICgzNzI5IHJvd3MpDQpgYGB7cn0NCnByZXNhYl9taXNzaW5ndmFscyA8LSBwcmVzYWJbIWlzLm5hKHByZXNhYiR0ZW1wX2RlcHRoKSwgXQ0KbnJvdyhwcmVzYWJfbWlzc2luZ3ZhbHMpICMxMjY1NzAgLSBjb3JyZWN0DQpgYGANCmNoZWNrIGZvciBtaXNzaW5nIHZhbHMNCmBgYHtyfQ0KcHJlc2VuY2Vfd2RlcHRoX25vbzIgPC0gcHJlc2FiX21pc3Npbmd2YWxzW2lzLm5hKHByZXNhYl9taXNzaW5ndmFscyRvMl9kZXB0aCksIF0NCm5yb3cocHJlc2VuY2Vfd2RlcHRoX25vbzIpICNqdXN0IHRvIGNoZWNrIGl0IGhhcyBtYXBwZWQNCnByZXNlbmNlX3dkZXB0aF9ub3NhbGluaXR5IDwtIHByZXNhYl9taXNzaW5ndmFsc1tpcy5uYShwcmVzYWJfbWlzc2luZ3ZhbHMkc2FsaW5pdHlfZGVwdGgpLCBdDQpucm93KHByZXNlbmNlX3dkZXB0aF9ub3NhbGluaXR5KSAjanVzdCB0byBjaGVjayBpdCBoYXMgbWFwcGVkDQpwcmVzZW5jZV93ZGVwdGhfbm90ZW1wIDwtIHByZXNhYl9taXNzaW5ndmFsc1tpcy5uYShwcmVzYWJfbWlzc2luZ3ZhbHMkdGVtcF9kZXB0aCksIF0NCm5yb3cocHJlc2VuY2Vfd2RlcHRoX25vdGVtcCkgI2p1c3QgdG8gY2hlY2sgaXQgaGFzIG1hcHBlZA0KYGBgDQpvayBub3cgcmVtb3ZlIHJvdyB3aGVyZSBvMl9kZXB0aCBpcyBtaXNzaW5nDQpgYGB7cn0NCnByZXNhYl9taXNzaW5ndmFscyA8LSBwcmVzYWJfbWlzc2luZ3ZhbHNbIWlzLm5hKHByZXNhYl9taXNzaW5ndmFscyRvMl9kZXB0aCksIF0NCm5yb3cocHJlc2FiX21pc3Npbmd2YWxzKSAjMTI2MzYwIC0gY29ycmVjdA0KYGBgDQpvayBhcyBzdW1tYXJpZXMgb2JzZXJ2YXRpb25zIHBlciBtb250aA0KDQpgYGB7cn0NCnByZXNhYl9taXNzaW5ndmFsc19vYnMgPC0gc3Vic2V0KHByZXNhYl9taXNzaW5ndmFscywgb2NjdXJyZW5jZSA9PSAiMSIpDQpvYnNfYnlfbW9udGggPC0gY291bnQocHJlc2FiX21pc3Npbmd2YWxzX29icywgIm1vbnRoIikNCm9ic19ieV9tb250aA0KYGBgDQoNCmFuZCBiZWZvcmUgaXQgd2FzLi4uDQoNCmBgYHtyfQ0Kb2JzX2J5X21vbnRoX3ByZXMgPC0gY291bnQocHJlc2VuY2UsICJtb250aCIpDQpvYnNfYnlfbW9udGhfcHJlcw0KYGBgDQoNCmp1c3QgY2hlY2sgdGhlIG9icyB0aGF0IHlvdSByZW1vdmVkIChzYXZlZCBhcyBwcmVzZW5jZV9uYS5jc3YpIHRvIHNlZSBpZiB0aGUgcmVwb3J0ZWQgZGVwdGggaXMgZGVlcGVyIHRoYW4gdGhlIGdlYmNvIGRlcnJpdmVkIGJvdHRvbSBkZXB0aA0KDQpgYGB7cn0NCnByZXNlbmNlX25hX2dyZWF0ZXIgPC0gc3Vic2V0KHByZXNlbmNlX05BLCBkZXB0aF9sYXllciA+IGJvdHRvbV9kZXB0aF9nbG9yeXMpDQpwcmVzZW5jZV9uYV9ncmVhdGVyIA0KYGBgDQoNCm9rIHBvdGVudGlhbGx5IGkgbWlnaHQgYmUgYWJsZSB0byBjbGF3IGJhY2sgMTUwIHBvaW50cy4uLmltIG5vdCBzdXJlIGl0cyB3b3J0aCBpdA0KDQojbWF4ZW50Pw0KDQpgYGB7cn0NCmxpYnJhcnkoInJhc3RlciIpDQpsaWJyYXJ5KCJkaXNtbyIpDQpsaWJyYXJ5KCJyZ2VvcyIpDQpgYGANCg0K